我想再检查一下我对移动语义的理解。我的推理是否有遗漏。
#include <iostream>
using std::cout;
struct A
{
A() {cout<<"Constructor\n";}
~A() {cout<<"Desctuctor\n";}
A(const A&) {cout<<"Copy Constructor\n";}
A(A&&) noexcept {cout<<"Move Constructor\n";}
int x{1};
};
int f1(A a)
{
cout<<"f1(A a)\n";
return a.x;
}
int f2 (A&& a)
{
cout<<"f2 (A&& a)\n";
return a.x;
}
int main()
{
A a1, a2;
f1(std::move(a1));
f2(std::move(a2));
}
输出:
Constructor
Constructor
Move Constructor
f1(A a)
Desctuctor
f2 (A&& a)
Desctuctor
Desctuctor
根据我所看到的 f2()
所以我现在的理解是,如果我要使用移动语义,我最好总是写functionmethods签名来接受r值,以避免任何不必要的副本。或者我还遗漏了什么?
你几乎总是最好只取你要保留的输入值(除了奇数类型,它们的移动成本非常高)。
它保持了相同的性能水平(在常见的情况下),并使你的代码非常简单易懂。 它还能让你的代码非常清楚地保持值(因为它保证会被移出),因为rvalue引用不会强制执行。
正如你所看到的,当去掉print语句时,你的例子的时序和生成的代码是相同的。 http:/quick-bench.comADU4fzd0ISk0UrLboVhC-Pd7RmI