RVO,移动语义和争取最佳代码的斗争

5 c++ optimization move-semantics return-value-optimization emplace

如果我正确地得到它,移动语义允许从临时的,未命名的对象移动和重用资源.RVO虽然先前的移动语义更进一步,但"窃取"整个对象以避免额外的构造函数调用和赋值/复制函数.

这对我来说似乎有点反直觉,如果被调用的构造函数直接使用最终左值目标的地址直接将数据放在用户需要的地方,那么它会不会更快,更简单,用户更明显?

我的意思是,"在这个位置创建这个对象"似乎比"在某处创建这个对象,然后将其复制到正确的位置"更直观.

小智 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;
}
Run Code Online (Sandbox Code Playgroud)

复制省略:g ++ -std = c ++ 11 src-test/main.cc

Construct
Destruct
Run Code Online (Sandbox Code Playgroud)

没有副本省略:g ++ -std = c ++ 11 -fno-elide-constructors src-test/main.cc

Construct
Move
Destruct
Move
Destruct
Destruct
Run Code Online (Sandbox Code Playgroud)

知道构建程序/库的硬件的编译器能够应用(可选)复制省略.C++语言本身并不了解硬件特定的返回机制.因此,在这种情况下不可能在某个地址构建.