6

当编译器不能使用RVONRVO时,移动语义会很有用。但是在什么情况下编译器不能使用这些特性呢?

4

2 回答 2

5

答案是它取决于编译器和情况。例如,控制流分支可能会混淆优化器。维基百科给出了这个例子:

#include <string>
std::string f(bool cond = false) {
  std::string first("first");
  std::string second("second");
  // the function may return one of two named objects
  // depending on its argument. RVO might not be applied
  return cond ? first : second;
}

int main() {
  std::string result = f();
}
于 2012-05-09T21:15:14.480 回答
3

好吧,与其说编译器是否可以使用 RVO,不如说它是否可以避免复制构造。

考虑:

struct Blah
{
    int x;
    Blah( int const _x ): x( _x ) { cout << "Hum de dum " << x << endl; }
};

Blah foo()
{
    Blah const a( 1 );
    if( fermatWasRight() ) { return Blah( 2 ); }
    return a;
}

在此处获取副作用(构造函数的输出)乍一看与a在调用者提供的存储中直接构造非常不兼容。但是如果编译器足够聪明,那么它可以注意到销毁这个对象是一个空操作。更一般地说,对于任何特定情况,如果编译器足够聪明,那么无论我们多么偷偷地设计代码,它都可以设法避免复制操作。

虽然我不确定正式的形式,但上述情况,对象中有更多的有效负载,因此复制会更昂贵,这是移动语义可以提供帮助的一种情况,因此无论编译器的智能如何,都可以保证优化(或不)。

于 2012-05-09T21:13:07.693 回答