在过去,我们接受过培训,使用参考传递的结果参数,以避免不必要地复制数据。
然而,对于更聪明的编译器 - 特别是对C ++ 11 的扩展仍然需要吗?
具体来说,是否有任何理由在2018年使用现代C ++ 11 / C ++ 14编译器(仍)使用
void Filter(vector<CObject*> &elements, vector<CObject*> &outElements);
而不是简单地返回矢量,即
vector<CObject*> Filter(vector<CObject*> &elements);
提前感谢所有见解!
答案 0 :(得分:10)
特别是C ++ 11的扩展是否还需要?
没有。在最佳情况下,RVO (返回值优化)将启动,这将完全忽略任何复制/移动。
在最坏的情况下,对象将被移出函数。 std::vector
的移动非常便宜(仅与几个指针交换相比)。
这是因为表达式Filter(some_input)
是std::vector<CObject*>
类型的右值,而std::vector
的构造函数有一个重载接受右值参考:see (6) here。
答案 1 :(得分:2)
在过去,我们接受过培训,使用参考传递的结果参数,以避免不必要地复制数据。
实际上,即使一个人使用旧的C ++编译器,这也是一个非常糟糕的建议:先写清楚,然后再写效率。
特别是,按参考值返回可防止调用者const
中的值(提高清晰度和提供其他优化机会)。
当然,如果分析显示这是性能瓶颈,那么必须进行必要的更改。使用RVO和NRVO(现在很常见),并将语义作为备份移动,现在它不太可能成为性能瓶颈。
答案 2 :(得分:0)
从函数返回值时,编译器应用返回值优化以避免复制。 所以,两种情况都是相似的。 您可以阅读更多there。