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 member std::vector<T>::push_back(T const& v)
is conceptually equivalent to (leaving the allocator template parameter out as it is irrelevant for this discussion)
template <typename T>
void std::vector<T>::push_back(T const& v) {
this->insert(this->end(), v);
}
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 T
argument needs to be assignable. It seems that the standard library shipping with MSVC++ doesn't delegate the operation but does all the necessary handling, ie, resizing the array and moving the objects appropriately when running out of space, in push_back()
. It isn't quite clear what the requirements are on the type T
to be able to use push_back()
.
In principle, a container supporting both T const
and an insert()
operation in the middle would be possible, though: Nothing requires the internal storage to be T
rather than typename std::remove_const<T>::type
while exposing a T&
in the interface. It is necessary to be a bit careful about the const
-version ofoperations like operator[]()
because just using T const&
as the return type when T
is some type S const
would result in a type S const const
. In C++ 2003 this would be an error, in C++ 2011 I think the const
are just collapsed. To be safe you could use typename std::add_const<T>::type&
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.