开发者

How do I add an object to a vector<const Obj&>?

I am not sure why this doesn't compile:

std::vector< const Obj& > myVector;

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

Sorry, a bit of additional info on 开发者_StackOverflowwhat I'm trying to achieve: I can't change the signature of foo without breaking an interface, but I just want to hang onto the Objects that get passed through foo. I do want to store pointers to them, but I'm confused about the syntax of how to do that.


You can't have an vector of references. as the things in a vector must be copyable and assignable, and references are neither of these. You probably want a vector of pointers:

std::vector< const Obj * > myVector;

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


I'm not sure if you can put references into a container like this. Use

 std::vector<const Obj *> myVector

instead as that's semantically equivalent anyway.


You cannot use references as the types in a vector. You can use raw pointers, smart pointers (boost/std::tr1 shared_ptr) or other constructs like boost::ref and boost::cref that provide wrappers around plain references to adapt to containers.


Vectors only work with value types; you cannot have a vector of references.

Part of the reason is that references must be bound to an existing variable as they are created, and they can never be re-bound. For a vector to be able to hold 10 elements at their "default" value is impossible with a reference type:

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

Similarly, you cannot re-assign a value to a reference (unless your intention was to modify the value of the original variable) so suddenly myVec[0] = 7 doesn't work either.


Alternatively you can use boost::ref to store references, but it is much like storing pointers.

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

As per your edits, if you want to store pointers, you can just write something like:

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

If you use boost::ref or boost::cref:

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

(probably you can ommit the last boost::cref in the body too, but I don't have now a compiler at hand).


The C++ Standard in chapater 23.1 Container requirements specifies:

3 The type of objects stored in these components must meet the requirements of CopyConstructible types (20.1.3), and the additional requirements of Assignable types.

In other words, a type T is usable with standard C++ containers as value type as long as it defines copy constructor. The CopyConstructible concept is explain by the standard in the cited chapater but Boost manual explains clearly and shortly what means a type is CopyConstructible

Reference does not fulfil this requirement.


You cannot store references in an STL container because references are not copy constructable. TR1 contains a reference wrapper if you really need to "simulate" storing references. Storing smart pointers (e.g. tr1::shared_ptr) or object instances is usually better.


Aside from problems with references being the target type for a container, you can't have const objects as the target type for a container because the type of objects that a container is instantiated with must be "Assignable" as well as "CopyConstructable" (23.1 Container requirements). Const objects aren't assignable.

To be assignable, after a 't = u operation, t must be equivalent to u where t is of type T - the type the container was instantiated with.

However, as mentioned in other answers, you can put pointers to const objects in containers.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜