tags:

views:

134

answers:

3

For example, std::vector<int&> vec_int; this seems to be invalid in c++. Why is this invalid?

+6  A: 

STL containers need to be able to construct objects with default constructor. You cannot do that with a reference. A reference is guaranteed to be valid, therefore it always has to be initialized with assignment.

You need to use a pointer instead.

ypnos
There is another reason. References cannot be assigned. I believe that `::std::vector` requires that the thing stored in it be assignable.
Omnifarious
Two notes here. One can use also `boost::ref` to store references in containers. And about pointers, also `boost::shared_ptr` to store them safely wrt. memory allocation.
Diego Sevilla
Assignability is probably the culprit here. AFAIK, containers don't require default constructor, unless you call methods that use it (e.g `resize()` with the default and similar).
visitor
@visitor: Not right, you need default constructor in any case. It will fail as the templated methods need to be preprocessed in any case.
ypnos
Sorry that's not right. It's not a requirement for `T` to be default constructible.
Johannes Schaub - litb
@chrispy: Done :)
Diego Sevilla
Armen Tsirunyan
"The default constructor is not required. Certain container class member function signatures specify thedefault constructor as a default argument. T() shall be a well-defined expression (8.5) if one of those sig-natures is called using the default argument (8.3.6)."
Johannes Schaub - litb
Thank you guys for clarification. I never got it compiled without default constructor at the point of creating the vector with gcc though.
ypnos
+3  A: 

Internally, a vector<T> uses an array to store a sequence of T objects. Since references aren't objects, there is no such thing as an array of references (see 8.3.2 §5 in the standard), thus reference types cannot be used to parameterize the vector template.

What you probably want is a vector of smart pointers such as std::vector<boost::shared_ptr<T> > or a dedicated pointer container such as boost::ptr_vector<T>.

FredOverflow
+3  A: 

Answer, as per chryspi request above. As commented in other responses, you cannot use references directly as references don't exist by themselves.

You can use references, however, but by using the boost::reference_wrapper<T> utility class:

    typedef boost::reference_wrapper<int> intref;
    std::vector<intref> v;
    int i;
    i = 9;

    v.push_back (boost::ref (i));  // store &i

    int& j = v[0];
    j = 10;
    //v[0].get() = 10;

    std::cout << i << std::endl; // prints 10

I put as an example how to modify directly the element v[0]. Note that it is somewhat tricky (you have to call the get() method) because you get a boost::reference_wrapper<T> instead of an actual reference.

For storing pointers safely with respect to memory, you can use boost::shared_ptr similarly.

Diego Sevilla