tags:

views:

1844

answers:

7

When I do this:

std::vector<int> hello;

Everything works great. However, when I make it a vector instead:

std::vector<int &> hello;

I get horrible errors like "error C2528: 'pointer' : pointer to reference is illegal".

I want to put a bunch of references to structs into a vector, so that I don't have to meddle with pointers. Why is vector throwing a tantrum about this? Is my only option to use a vector of pointers instead?

+15  A: 

You have to settle with pointers. As the compiler error says, internally, vector will want to have a variable of type T* which won't work if T is a reference.

Mehrdad Afshari
Even if you could create a T* with a reference T, something like hello[0]=getIntRef() wouldn't work because you cannot re-assign references. This would make vector<int)
Naaff
+2  A: 

It's a flaw in the C++ language. You can't take the address of a reference, since attempting to do so would result in the address of the object being referred to, and thus you can never get a pointer to a reference. std::vector works with pointers to its elements, so the values being stored need to be able to be pointed to. You'll have to use pointers instead.

Adam Rosenfield
I guess it could be implemented using a void * buffer and placement new. Not that this would make much sense.
peterchen
"Flaw in the language" is too strong. It is by design. I don't think it is required that vector works with pointers to elements. However it is required that the element be assignable. References are not.
Brian Neal
+3  A: 

By their very nature, reference can only be set at the time they are created, i.e. the following two lines have very different affects:

int & A = B;   // makes A an alias for B
      A = C;   // assigns value of C to B.

Futher, this is illegal.

int & D;       // must be set to a int variable.

However, when you create a vector, there is no way to assign values to it's items at creation. You are essentially just making a whole bunch of the last example.

James Curran
"when you create a vector, there is no way to assign values to it's items at creation" I don't understand what you mean by this statement. What are "its items at creation"? I can create an empty vector. And I can add items with .push_back(). You are just pointing out that references are not default-constructible. But I can definitely have vectors of classes that are not default-constructible.
newacct
The element ype of std::vector<T> is not required to be default constructible. You can write struct A { A(int); private: A(); }; vector<A> a; just fine - as long as you don't use such methods that require it to be default constructible (like v.resize(100); - but instead you will need to do v.resize(100, A(1)); )
Johannes Schaub - litb
And how would you write such a push_back() in this case? It will still use assignment, not construction.
James Curran
Johannes Schaub - litb
+22  A: 

The component type of containers like vectors must be assignable. References are not assignable (you can only initialize them once when they are declared, and you cannot make them reference something else later). Other non-assignable types are also not allowed as components of containers, e.g. vector<const int> is not allowed.

newacct
Are you saying I can't have a vector of vectors? (I'm sure I've done that...)
James Curran
Yes, a std::vector< std::vector<int> > is correct, std::vector is assignable.
Martin Cote
Johannes Schaub - litb
Checking the assignable concept at http://www.boost.org/doc/libs/1_39_0/doc/html/Assignable.html all operations except the swap are valid on references.
Amit Kumar
+9  A: 

boost::ptr_vector<int> will work.

Edit: was a suggestion to use std::vector< boost::ref<int> >, which will not work because you can't default-construct a boost::ref.

Shmoopty
But you can have a vector or non default-constructible types, right? You only have to be careful not to use the default ctor. of the vector
Manuel
+1  A: 

As other have mentioned, you will probably end up using a vector of pointers instead.

However, you may want to consider using a ptr_vector instead!

Martin Cote
A: 

Further reading - rvalues and lvalues in C++0x (:

Dark