35

是否可以在不复制的情况下从函数返回标准容器?

示例代码:

std::vector<A> MyFunc();

...

std::vector<A> b = MyFunc();

据我了解,这会将返回值复制到一个新向量 b 中。使函数返回引用或类似的东西可以避免复制吗?

4

3 回答 3

31

如果您的编译器支持 NRVO,那么只要返回对象的函数满足某些条件,就不会进行复制。值得庆幸的是,这最终被添加到Visual C++ 2005 (v8.0) 中,如果容器很大,这显然会对性能产生重大影响。

如果您自己的编译器文档没有说明它是否受支持,您应该能够将 C++ 代码编译为汇编器(在优化/发布模式下)并使用简单的示例函数检查所做的工作。

这里还有一个很棒的更广泛的讨论

于 2010-09-15T19:44:10.363 回答
17

绑定到const引用的右值(“临时”)的生命周期将延长到引用生命周期的末尾。因此,如果您不需要修改该向量,则可以执行以下操作:

const std::vector<A>& b = MyFunc();

如果您需要修改向量,只需以最容易阅读的方式对其进行编码,直到您有证据(通过分析获得)该行甚至在性能方面也很重要。

否则,依靠 C++1x 及其右值引用和移动语义“很快就会出现”并优化该副本,而无需您做任何事情。

于 2010-09-15T20:44:41.903 回答
3

如果您可以修改函数的签名,那么您可以使用

std::vector<A>& MyFunc(); 

或者

void MyFunc(std::vector<A>& vect);

您也可以返回一个智能指针,但这涉及到新对象。

some_smart_pointer<std::vector<A>> MyFunc();

高温高压

于 2010-09-15T19:50:35.217 回答