Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference of STL vector that contains references to objects generates error in C++. Why?

Why can't I have a reference to std::vector that contains references to objects? The following code generates a compile error in Visual C++ 2010:

void Map::Filter( Object::Type type, std::vector<Object&>& list )
{
  for ( register int y = 0; y < MAP_H; y++ )
    for ( register int x = 0; x < MAP_W; x++ ) {
      if ( under[y][x].GetType() == type )
        list.push_back(under[y][x]);
      if ( above[y][x].GetType() == type )
        list.push_back(above[y][x]);
    }
}

Summarized compile error:

c:\program files\microsoft visual studio 10.0\vc\include\xmemory(137): error C2528: 'pointer' : pointer to reference is illegal
c:\program files\microsoft visual studio 10.0\vc\include\vector(421) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled

I solved the problem by switching from a "vector of references to objects" to a "vector of pointers to objects". I just can't understand why I can't have a reference to a vector of references.

like image 992
Fernando Aires Castello Avatar asked Dec 30 '25 18:12

Fernando Aires Castello


1 Answers

The standard Containers use an Allocator to allocate memory and construct and destruct elements. The Allocator requirements are specified for an Allocator class X which is responsible for allocating objects of type T. The type T is specified as "any non-const, non-reference object type" (Table 27). So there simply are no requirements for an Allocator of reference objects. This means trying to create a container of reference type will lead you straight to undefined behaviour.

Table 27 is found in §17.6.3.5 Allocator requirements:

enter image description here

An alternative is to use a vector of std::reference_wrapper and push_back your elements with:

list.push_back(std::ref(under[y][x]));

Another alternative is using raw pointers or perhaps using an implementation of the World's Dumbest Smart Pointer.

Also, I recommend not calling your vector list - there is a std::list container type. What is it a list of? cats? people? bananas?

like image 78
Joseph Mansfield Avatar answered Jan 01 '26 08:01

Joseph Mansfield



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!