我仍然不太确定何时返回值是C ++的好主意。在下面的例子中,可以吗?
vector<int> to_vec(const Eigen::MatrixXi& in){
vector<int> out;
// copy contents of in into out
return out;
}
Eigen::MatrixXi to_eigen(const vector<int>& in){
Eigen::MatrixXi out;
// copy contents of in into out
return out
}
根据这些对象vector
和MatrixXi
的实际工作方式,可能会产生昂贵的副本。另一方面,我假设他们利用C ++的移动功能,通过重用基础数据来廉价地复制。
如果不完全了解实施情况,我可以假设什么?
答案 0 :(得分:3)
在您声明局部变量,初始化并按值返回的情况下,您可以非常安全地假设您的编译器将elide副本。
这种情况称为命名的返回值优化。本质上,它不是在函数调用中分配返回值,而是在调用站点完成并作为引用传入。按价值返回是这里的最佳选择,因为您不需要在呼叫站点声明变量以传入,但性能将与您一样。
在C ++ 17中,copy elision will be mandatory在大多数情况下涉及prvalues(例如T t = get_t();
或return get_t()
),但对于NRVO仍然是可选的。
答案 1 :(得分:2)
关于C ++中返回值的Thumb规则是:
至于(3) - 这是C ++的一个已知问题 - 我们都知道当一个对象按值返回时 - 它会激活复制构造函数。这理论上是真的,但几乎错误。打开优化时,编译器将在对象上使用 copy elision 。
copy elision 是一种优化技术,可以在调用者范围内而不是在被调用者范围内创建值,从而防止昂贵的副本。对该对象的修改将在被调用者范围内进行。
对于(1)和(2),还有关于协同程序和生成器的角落情况,但除非您知道您正在处理它们,否则(1)和(2)始终有效。