2010-01-25 43 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

引用不符合此要求。