2010-01-25 67 views
4

我不知道爲什麼,這並不編譯:如何將對象添加到矢量<const Obj&>?

std::vector< const Obj& > myVector; 

void foo(const Obj& obj) 
{ 
    myVector.push_back(obj); 
} 

對不起,在我想要實現多一點額外的信息:在不破壞的界面我無法改變foo的簽名,但我只想掛在通過foo傳遞的對象上。我確實想要存儲指向它們的指針,但我對如何做到這一點的語法感到困惑。

回答

15

你不能引用的一個載體。因爲矢量中的東西必須是可複製和可分配的,而引用不是這些東西。您可能希望指針的向量:

std::vector< const Obj * > myVector; 

void foo(const Obj & obj) 
{ 
    myVector.push_back(& obj); 
} 
+0

+1快速且完整的答案。 – AraK 2010-01-25 21:49:45

4

我不知道,如果你可以把引用到這樣的容器中。使用

std::vector<const Obj *> myVector 

而不管它是否在語義上相同。

4

不能使用作爲一個載體類型的引用。您可以使用原始指針,智能指針(boost/std :: tr1 shared_ptr)或其他構造如boost::refboost::cref,它們提供了簡單引用的包裝以適應容器。

4

向量只能使用值類型;你不能有一個引用向量。原因

部分是引用必須綁定到一個現有的變量,因爲他們創建的,他們永遠不能重新綁定。對於一個載體能夠在他們的「默認」值來保存10個元素是不可能的引用類型:

std::vector<const T& obj>(10); // cannot work 

同樣,你不能在價值進行重新分配給一個參考(除非你的目的是要修改原始變量的值),所以突然myVec[0] = 7也不起作用。

4

或者您可以使用boost::ref存儲引用,但它很像存儲指針。

std::vector< boost::ref<Obj> > myVector; 

根據您的編輯,如果你想存儲的指針,你可以只寫是這樣的:如果你使用boost :: ref或提振:: CREF

std::vector < const Obj* > myVector; 
void foo(const Obj& obj) 
{ 
    myVector.push_back(&obj); 
} 

std::vector < boost::cref <Obj> > myVector; 
void foo(const Obj& obj) 
{ 
    myVector.push_back(boost::cref<Obj>(obj)); 
} 

(可能是您可以ommit最後的boost :: CREF在體內過多,但我現在不手邊有一個編譯器)。

1

您不能將引用存儲在STL容器中,因爲引用不是可複製構造的。如果你真的需要「模擬」存儲引用,TR1包含一個引用包裝器。存儲智能指針(例如tr1 :: shared_ptr)或對象實例通常更好。

1

除了引用是容器的目標類型的問題之外,不能將const對象作爲容器的目標類型,因爲容器實例化的對象的類型必須是「Assignable」以及「CopyConstructable」(23.1容器要求)。 Const對象不可分配。

要分配,一個't = u操作之後,t必須等於u其中tT類型的 - 該容器用實例化的類型。

但是,正如其他答案中所述,您可以將指針指向容器中的const對象。

2

C++標準在chapater 23.1集裝箱要求指定:

3的類型存儲在這些 組件必須滿足的要求對象的複製構造類型(20.1.3), 和附加的 要求的可指定類型。

換句話說,只要定義了複製構造函數,類型T就可以與標準C++容器一起用作值類型。 CopyConstructible概念由引用的文檔中的標準解釋,但Boost手冊中明確解釋了什麼意思是類型CopyConstructible

引用不符合此要求。