2011-11-02 119 views
3

在一个函数中,哪个“返回”会更合适?返回向量<Foo>或shared_ptr <vector<Foo>>?

A. vector<Foo>

B. shared_ptr<vector<Foor>>

换句话说,哪个副本不那么重,你会怎么做,为什么?

+0

可能的重复/相关:http://stackoverflow.com/questions/3721217/returning-ac-stdvector-without-a-copy – larsmoa

+1

检查你的编译器,但你通常可以假设elision会发生,在这种情况下,return-按价值是最快的方法。它也是语义的最佳方式(idempotence,const结果赋值等),请参阅[本文](http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/) – spraff

+0

为什么不是'unique_ptr'选项?返回'shared_ptr'意味着该函数保留一个副本;返回一个'unique_ptr'让大家知道所有权正在被完全转移。 –

回答

6

我想回国shared_ptr<vector<T>>很少有用。我只会这样做,如果几个对象在哪里容纳一个共享的矢量,他们可以操纵。对我来说,这表明了一个设计缺陷。更好的选择可能是通过const引用返回。这可以避免(一个潜在的昂贵的)复制操作,但不允许访问者更改向量。

如果您要返回本地std::vector您也可以通过参数返回它。

如果您确实想要返回shared_ptr<vector<T>>,请考虑shared_ptr<const vector<T>>是否可以完成这项工作(该矢量可以被许多人检查,但只能由所有者操纵)。

然而,A通常比B更昂贵,但是返回值优化在这里经常适用。对于C++ 11 std::vector有一个移动构造函数,可以保证返回本地std::vector不需要昂贵的复制操作。

记住,不要过早地优化:)

+0

所有这些都忽略了RVO/NRVO,这使得问题首先得到解决。 – ildjarn

2

返回shared_ptr<vector<Foo>>保证不会发生额外的副本。

返回vector<Foo>可能如果使用返回值优化(RVO)或者使用C++ 11中的移动语义,请避免额外的副本。但是,如果避免复制很重要,我不会使用它(即使您可以确保这些优化始终可用),因为我认为在实际意义上不复制时使用return-a-copy语义并不是一个好主意。

我可能会与其中的一个去,但要看:

  • 传递一个参考vector<Foo>作为参数
  • 通插入迭代器(如back_inserter),而不是
+0

:对,因为它将在函数范围的末尾被销毁。我在不同的平台上交叉编译,使用xCode,vs2010的ios。那你是否建议呢? –

+0

@AlonAmir查看更新后的答案。如果避免复制很重要,不要通过值传递'vector'。 – hamstergene

+4

*传递给参数'vector '作为参数*:我不会,如果函数*在内部创建*向量,那么它是一个返回值。我知道的所有编译器的调用约定,如果返回类型不适合寄存器,将为您实现:调用者分配空间并将指针传递给calle,然后被调用者用真正的对象(根据代码调用相应的构造函数)。效果是,您可以获得完全相同成本的更清晰的界面。 –

0

在C++ 03,喜欢:

  1. 如果提供由const引用访问成员,回报。
  2. 否则,如果返回本地,则使用out参考参数。

在C++ 11,宁可:

  1. 如果提供由常量引用访问构件,返回。
  2. 否则如果返回本地,则按值返回,因为移动建设会将 避免过多副本。

你想要返回一个引用计数智能指针的情况下,多个具有不相交的生命期的对象都将要访问该对象。然而,这并不是最常见的情况,但它确实经常发生。

+0

我不同意#2的建议。复制elision/RVO /他们想要调用的任何东西 - 它可以使很多容器返回便宜。除非你返回一个临时的,否则移动构造函数只有在你明确地通过'std :: move'请求时才会被调用。无论哪种方式,最好使用copy elision。 –

+0

C++ 03:你永远不会返回一个局部变量的引用。 –

+0

@BarnabasSzabolcs - 你应该更仔细地解析我的语言。如果你将返回的东西是本地的函数,那么通过引用作为参数*来引用对象的一个​​实例。 –

相关问题