The following is bad:
vector<const int> vec;
The problem is that the template type needs to be assignable. The following code compiles [EDIT: in Visual Studio 2010], demonstrating a problem with the above:
vector<const int> vec;
vec.push_back(6);
vec[0] += 4;
With more complicated types, this can be a serious problem.
My first question is whether there is a reason for this behavior. It seems to me like it might be possible to make const containers that disallow the above and non-const containers that allow it.
Second, is there a way to make containers that function in this way?
Third, what is actually happening here (with a user type)? I realize it is undefined behavior, but how is the STL even compiling this at all?
The reason
std::vector<T const>isn’t allowed is that the object in a vector may need to be reshuffled when inserting at a different place than the beginning. Now, the memberstd::vector<T>::push_back(T const& v)is conceptually equivalent to (leaving the allocator template parameter out as it is irrelevant for this discussion)which seems to be how it is implemented on some implementations. Now, this operation would requires, in general, that some objects might need to be moved and, thus, the
Targument needs to be assignable. It seems that the standard library shipping with MSVC++ doesn’t delegate the operation but does all the necessary handling, i.e., resizing the array and moving the objects appropriately when running out of space, inpush_back(). It isn’t quite clear what the requirements are on the typeTto be able to usepush_back().In principle, a container supporting both
T constand aninsert()operation in the middle would be possible, though: Nothing requires the internal storage to beTrather thantypename std::remove_const<T>::typewhile exposing aT&in the interface. It is necessary to be a bit careful about theconst-version ofoperations likeoperator[]()because just usingT const&as the return type whenTis some typeS constwould result in a typeS const const. In C++ 2003 this would be an error, in C++ 2011 I think theconstare just collapsed. To be safe you could usetypename std::add_const<T>::type&.