【发布时间】:2013-12-19 18:39:51
【问题描述】:
我试图弄清楚 RVO 和 NRVO 如何与新的 C++11 移动运算符一起工作。 我用几个例子起草了一个虚拟类。
编辑:只显示最重要的代码部分。
完整的源代码可用here。
我有两个函数将类作为引用并返回值或引用:
VOpt& fChangeClassRetRef(VOpt &m) {
m.setX(21);
return m;
}
VOpt fChangeClassRetValue(VOpt &m) {
m.setX(21);
return m;
}
当我调用这些函数时,输出如下:
VOpt &m14 = fChangeClassRetRef(m13);
m14 = fChangeClassRetRef(m11);
-> Copy Assignment Operator
m14 = fChangeClassRetValue(m11);
-> Copy Constructor
-> C++11 Move Operator
当使用左值引用时,不会调用复制构造函数。否则,那些函数(接收引用作为参数)仍然调用复制构造函数。
此功能是否依赖于编译器?我做错了吗?
【问题讨论】:
-
概念是正交的。如果有 RVO 或 NRVO,就没有移动任何东西的余地。
-
这里有很多代码 - 最好将程序简化到让您感到困惑的情况,并说明这些情况的预期行为。
-
更有趣的情况是,如果您删除所有引用(按值传递 m,按值返回)。然后 C++03 允许复制省略(尽管没有编译器这样做),但 C++11 不允许。不过它确实使用了移动构造函数。
-
@MarcGlisse:呃,什么? C++11 同样允许复制省略。
-
@MarcGlisse:你到底在说什么? C++11 没有禁止任何在 C++03 中合法的复制省略。事实上,编译器何时可以执行隐式移动的定义是何时可以合法地删除副本。
标签: c++ c++11 move-semantics rvo nrvo