【发布时间】:2011-04-12 21:10:15
【问题描述】:
是否可以在不复制的情况下从函数返回标准容器?
示例代码:
std::vector<A> MyFunc();
...
std::vector<A> b = MyFunc();
据我了解,这会将返回值复制到一个新向量 b 中。使函数返回引用或类似的东西可以避免复制吗?
【问题讨论】:
标签: c++ stl copy return-value temporary
是否可以在不复制的情况下从函数返回标准容器?
示例代码:
std::vector<A> MyFunc();
...
std::vector<A> b = MyFunc();
据我了解,这会将返回值复制到一个新向量 b 中。使函数返回引用或类似的东西可以避免复制吗?
【问题讨论】:
标签: c++ stl copy return-value temporary
如果您的编译器支持 NRVO,那么只要返回对象的函数满足某些条件,就不会进行复制。值得庆幸的是,这最终被添加到 Visual C++ 2005 (v8.0) 中,如果容器很大,这显然会对性能产生重大的 +ve 影响。
如果您自己的编译器文档没有说明它是否受支持,您应该能够将 C++ 代码编译为汇编器(在优化/发布模式下)并使用简单的示例函数检查所做的工作。
还有一个很棒的更广泛的讨论here
【讨论】:
绑定到const 引用的右值(“临时”)的生命周期将延长到引用生命周期的末尾。因此,如果您不需要修改该向量,则可以执行以下操作:
const std::vector<A>& b = MyFunc();
如果您需要修改向量,只需以最容易阅读的方式对其进行编码,直到您有证据(通过分析获得)该行甚至在性能方面也很重要。
否则依赖于 C++1x 及其右值引用和移动语义“现在很快就会出现”并优化该副本,而无需您做任何事情。
【讨论】:
如果你可以修改函数的签名,那么你可以使用
std::vector<A>& MyFunc();
或
void MyFunc(std::vector<A>& vect);
您也可以返回一个智能指针,但这涉及到新对象。
some_smart_pointer<std::vector<A>> MyFunc();
HTH
【讨论】:
std::vector<A>& MyFunc(); 的问题是向量必须被分配到某个地方——MyFunc 不能在堆栈上分配它并返回一个引用。如果向量是类成员并且您只是返回对现有向量的引用,这是可能的。