当编译器不能使用RVO和NRVO时,移动语义会很有用。但是在什么情况下编译器不能使用这些特性呢?
问问题
1346 次
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 回答