【发布时间】:2019-05-29 09:44:24
【问题描述】:
请看一下这个傻函数,它应该只是说明问题和对真实代码的简化:
struct A;
A create(bool first){
A f(21), s(42);
if(first)
return f;
else
return s;
}
我了解,由于不清楚编译期间将返回哪个对象,我们不能期望总是执行返回值优化 (RVO)。
但是,人们可能期望在 50% 的情况下执行 RVO(假设 true/false 由于缺乏进一步信息而均匀分布):只需决定哪种情况 RVO(first==true 或first==false) 应该被执行并将其应用于此参数值,接受在其他情况下必须调用复制构造函数。
然而,这种“部分 RVO”并非适用于我可以使用的所有编译器(参见 gcc、clang 和 MSVC 的现场直播)——在这两种情况下(即 first==true 或 @987654330 @) 使用了复制构造函数,没有省略。
有什么东西导致上述情况下的“部分 RVO”无效,或者这是所有编译器都错过优化的不太可能的情况?
完整的程序:
#include <iostream>
struct A{
int val;
A(int val_):val(val_){}
A(const A&o):val(o.val){
std::cout<<"copying: "<<val<<"\n";
}
};
A create(bool first){
A f(21), s(42);
if(first)
return f;
else
return s;
}
int main(){
std::cout<<"With true: ";
create(true);
std::cout<<"With false: ";
create(false);
}
【问题讨论】:
-
在这种(不可否认的)简单情况下,一个简单的解决方法是使用 return 语句构建对象“内联”。如
if (first) return A(21); else return A(42); -
更好的是
return A(first ? 21 : 42);;-)
标签: c++ optimization rvo