我有一段通用代码,实例化后可以简化为:
struct A{...};
A f1(){
A ret;
std::pair<A&, int> p(ret, 1);
p = g(); // g returns a pair<A, int>, but I am not interested in g
return ret; // RVO :)
};
据我了解,这将与RVO一起使用。
问题是,这段其他代码是否会返回类型为A的对象,并启用RVO?
A f2(){
std::pair<A, int> p;
p = g();
return p.first; // RVO ?
};
我知道由于返回对象被遮蔽,它将不会执行RVO或者编译器可能无法选择“优化”。但我并没有看到它不能实现的根本原因,换句话说,为了保持一致性,它应该执行RVO(这是我想要的)。
我之所以问这个问题,是因为我觉得
f2
比f1
更优雅。这个最后版本是否应该执行RVO?如果是,那么它是否取决于编译器?
我的粗略测试使用gcc 8.1表明,在下面的
f2
和f3
中,RVO不起作用。struct A{
double something;
A() = default;
A(A const& other) : something(other.something){std::cerr << "cc" << '\n';}
A(A&& other) : something(other.something){std::cerr << "mc" << '\n';}
};
A f1(){
A ret;
std::pair<A&, int> p(ret, 1);
p.first.something = 5.;
return ret; // RVO :)
};
A f2(){
std::pair<A, int> p;//(ret, 1);
p.first.something = 5.;
return p.first; // no RVO :(
};
A f3(){
std::pair<A, int> p;//(ret, 1);
p.first.something = 5.;
return std::move(p).first; // no RVO :(
};
int main(){
A a1 = f1(); // prints nothing, RVO
A a2 = f2(); // prints "cc"; no RVO! Why?
A a3 = f3(); // prints "mc" (no much gain in this case); still no RVO!
}
return std::move(p.first);
。 - M.M