(N)RVO的完整示例

eme*_*esx 6 c++ move-semantics nrvo

我一直在阅读关于(N)RVO的内容,并且想要一个完整的场景描述.我希望这个问题能够为其他C++领导者提供帮助,以澄清他们的想法.

假设这种情况:

string get_string() {
    string x("racecar");
    //work on x...
    return x;
}

string a( get_string() );
string b = get_string();
Run Code Online (Sandbox Code Playgroud)

请暂时忽略C++ 11移动语义.

  • 如果没有执行(N)RVO,将执行多少个构造函数/赋值/析构函数?(请指出,他们参考哪些对象)
  • 如果应用(N)RVO会有什么变化?
  • 最后,假设std::string支持移动语义,C++ 11中的情况如何变化.

Ben*_*ley 6

1)在里面get_string,将使用构造函数构造一个字符串对象(x)const char*.

2)当函数返回时,内部构造的字符串将被复制构造到调用者空间中的临时字符串对象.

3)临时将复制构造a.

4)见1

5)见2

6)参见3,但副本将转到 b

使用RVO,可以通过隐形引用构造函数内部的临时值来消除2和5.通过进一步的复制省略(不是RVO),可以消除3和6.因此,我们使用构造函数留下2个const char*构造.

使用C++ 11移动语义,如果编译器足够好以完成所有复制省略,则情况根本不会改变.如果没有完成复制省略,则仍然存在2,3,5和6,但是变为移动而不是复制.与copy elision不同,这些移动不是可选的优化.符合标准的编译器必须执行它们,假设它尚未执行复制省略.