我知道返回通常不是一个好主意std::move
, i.e.
bigObject foo() { bigObject result; /*...*/ return std::move(result); }
而不是简单地
bigObject foo() { bigObject result; /*...*/ return result; }
因为它妨碍了返回值优化。但是,如果一个函数有多个不同的返回值,特别是像这样的函数,该怎么办?
class bar {
bigObject fixed_ret;
bool use_fixed_ret;
void prepare_object(bigObject&);
public:
bigObject foo() {
if(use_fixed_ret)
return fixed_ret;
else{
bigObject result;
prepare_object(result);
return result;
}
}
};
我认为在这样的函数中正常的返回值优化是不可能的,所以放入
return std::move(result);
在这里,或者我应该这样做(我认为更丑陋,但这是有争议的)
bigObject foo() {
bigObject result;
if(use_fixed_ret)
result = fixed_ret;
else{
prepare_object(result);
}
return result;
}
For local variables, there's no need to std::move
them in the return
statement most of the time†, since the language actually demands that this happens automatically:
§12.8 [class.copy] p32
当满足或将满足复制操作省略的条件时,除了源对象是函数参数这一事实之外,并且要复制的对象由左值指定,首先执行重载决策以选择复制的构造函数,就像该对象由右值指定一样。如果重载决策失败,或者所选构造函数的第一个参数的类型不是对象类型的右值引用(可能是 cv 限定的),则将再次执行重载决策,并将该对象视为左值。 [Note:无论是否发生复制省略,都必须执行此两阶段重载决策。如果不执行省略,它确定要调用的构造函数,并且即使省略调用,所选构造函数也必须可访问。——尾注 ]
† 复制省略的应用范围非常有限(§12.8/31
)。其中一项限制是,在处理 return 语句时,源对象的类型必须与函数的 cv 无限定返回类型相同。它也不适用于即将超出范围的局部变量的子对象。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)