当最后一次使用可移动对象时,编译器会自动使用移动语义吗?

22 c++ optimization rvalue-reference move-semantics c++11

我最近一直在研究右值参考,并得出结论,在任何地方使用pass-by-value进行完整的对象复制是非常有利的(为了完整的理由,请参阅例如如何在添加rvalue参考运算符时减少冗余代码重载?要速度?按值传递!),因为编译器可以自动在如情况下优化复制走f(std::move(a));,其中f被定义为void f(A a);.

传递价值的一个负面后果是,std::move即使在简单的情况下,所有代码都会被弄乱,例如:

void Object::value(A a) 
{
    value_ = std::move(a);
}
Run Code Online (Sandbox Code Playgroud)

显然,如果我只写下面的内容:

void Object::value(A a) 
{
    value_ = a;
}
Run Code Online (Sandbox Code Playgroud)

a即使没有提示,编译器也应该很难识别出它的生命周期即将结束,并且不会使用额外的副本来惩罚我.事实上,即使在复杂的函数中,编译器也应该能够识别它.

问题:

  1. C++ 0x标准是否允许此优化?

  2. 编译器是否使用它?即使在复杂的情况下,即函数由多行组成?

  3. 这种优化的可靠性如何,即我希望编译器能够像我期望编译器应用返回值优化那样使用它吗?

How*_*ant 17

C++ 0x标准是否允许此优化?

没有.

编译器是否使用它?即使在复杂的情况下,即函数由多行组成?

没有.

这种优化的可靠性如何,即我希望编译器能够像我期望编译器应用返回值优化那样使用它吗?

您应该使用print语句进行装饰A(const A&)A(A&&)运行您感兴趣的测试用例.如果这些用例是您设计的一部分,请不要忘记测试左值参数.

正确的答案将取决于复制和移动的成本A,Object::value实际有多少参数,以及您愿意忍受多少代码重复.

最后,要非常怀疑任何包含"总是"或"无处不在"等词语的指南.我goto偶尔会使用一次.但是其他程序员也有像"永远"这样的词汇goto.但是每隔一段时间,你就无法goto在速度和清晰度上击败它.

将有次你应该赞成对foo(const A&) foo(A&&)foo(A).有时候你不会.您的装饰复制和移动成员的实验将指导您.

  • 很难定义"最后使用".即使使用我们目前的定义,也可以检测隐式移动优化(因此它实际上不是优化).但达成了妥协.有助于实现这些妥协的是将其与回报值优化(这也是可检测的)联系起来.示例:在"最后一次使用"之前放置一个`B b(a);`.现在,如果你从`a`移动,`b.~B()`可以通过存储对'a`的引用来检测移动. (2认同)