我一直在阅读关于(N)RVO的内容,并且想要一个完整的场景描述。我希望这个问题能够为其他C ++学习者提供帮助,以澄清他们的想法。
假设这种情况:
string get_string() {
string x("racecar");
//work on x...
return x;
}
string a( get_string() );
string b = get_string();
请暂时忽略C ++ 11移动语义。
std::string
支持,C ++ 11中的情况如何变化?
移动的语义。答案 0 :(得分:6)
1)在get_string
内,将使用构造函数构造一个字符串对象(x),该构造函数采用const char*
。
2)当函数返回时,内部构造的字符串将被复制构造到调用者空间中的临时字符串对象。
3)临时将复制到a
。
4)见1
5)见2
6)见3,但副本将转到b
使用RVO,通过不可见的引用构造函数内部的临时值,可以消除2和5。通过进一步的复制省略(不是RVO),可以消除3和6。因此,我们只使用const char*
构造函数构建了2个构造。
使用C ++ 11移动语义,如果编译器足够好以完成所有复制省略,则情况根本不会改变。如果没有完成复制省略,则仍然存在2,3,5和6,但是变为移动而不是复制。与copy elision不同,这些移动不是可选的优化。符合标准的编译器必须执行它们,假设它尚未执行复制省略。