2011-11-02 117 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 - 你應該更仔細地解析我的語言。如果你將返回的東西是本地的函數,那麼通過引用作爲參數*來引用對象的一個​​實例。 –

相關問題