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

RVO, move semantics and the struggle towards optimal code

本文关键字:最佳 代码 移动 语义 RVO      更新时间:2023-10-16

如果我理解正确,移动语义允许从临时的、未命名的对象中移动和重用资源。RVO,尽管前面的move语义更进一步,"窃取"了整个对象,以避免额外的构造函数调用和赋值/复制函数。

这对我来说似乎有点违背直觉,如果被调用的构造函数直接使用最终左值目标的地址来直接将数据放置在用户需要的地方,这不是更快、简单、用户显而易见吗?

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

是的,这"有点违背直觉"。启用复制省略后,构造函数的所有副作用也将被消除。

#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省略构造函数src test/main.cc

Construct
Move
Destruct
Move
Destruct
Destruct

编译器知道程序/库是为什么硬件构建的,就能够应用(可选的)拷贝省略。C++语言本身并不知道硬件特定的返回机制。因此,在这种情况下,不可能在某个地址进行构造。