如果我正确理解,移动语义允许从临时的,未命名的对象中移动和重用资源。 RVO虽然先前的移动语义更进一步,但“窃取”整个对象以避免额外的构造函数调用和赋值/复制函数。
这对我来说似乎有点反直觉,如果被调用的构造函数直接使用最终左值目标的地址来直接将数据放到用户需要的地方,那么它会不会更快,更简单,用户更明显?
我的意思是,“在这个位置创建此对象”似乎比“在某处创建此对象,然后将其复制到正确的位置”更直观。
答案 0 :(得分:7)
是的,它“有点反直觉”。启用复制省略后,构造函数的所有副作用也都会被删除。
#include <iostream>
struct X {
X() { std::cout << "Construct" << std::endl; }
X(X&&) { std::cout << "Move" << std::endl; }
~X() { std::cout << "Destruct" << std::endl; };
};
X f() { return X(); }
int main()
{
X x(f());
return 0;
}
复制省略:g ++ -std = c ++ 11 src-test / main.cc
Construct
Destruct
没有拷贝省略:g ++ -std = c ++ 11 -fno-elide-constructors src-test / main.cc
Construct
Move
Destruct
Move
Destruct
Destruct
编译器知道构建程序/库的硬件,能够应用(可选)复制省略。 C ++语言本身并不了解硬件特定的返回机制。因此,在这种情况下不可能在某个地址构建。