Why is erasing via const_iterator allowed in C ++ 11?
As of GCC 4.9.2, it is now possible to compile C ++ 11 code that inserts or erases container elements via a const_iterator.
I see how it makes sense to insert to accept a const_iterator, but I'm afraid to understand why it makes sense to allow erasure through a const_iterator.
This issue was discussed earlier , but I have not seen an explanation of the rationale behind the behavior change.
The best answer I can think of is that the purpose of the change was to make the behavior of const_iterator similar to that of const T *.
Obviously, the main reason for allowing delete with const T * is to include declarations such as:
const T* x = new T;
....
delete x;
However, it also allows for the following less desirable behavior:
int** x = new int*[2];
x[0] = new int[2];
const int* y = x[0];
delete[] y; // deletes x[0] via a pointer-to-const
and I'm struggling to figure out why it's okay for a const_iterator to emulate this behavior.
source to share
erase
and insert
are non-t22> collection member functions. Non-const member functions are the correct way to map mutating operations.
The consistency of the arguments doesn't matter; they are not used to change anything. The collection can be changed because the collection is notconst
(contained in a hidden argument this
).
For comparison:
template <typename T>
std::vector<T>::iterator std::vector<T>::erase( std::vector<T>::const_iterator pos );
^^^^^ ok
for a similar overload that is NOT allowed
template <typename T>
std::vector<T>::iterator std::vector<T>::erase( std::vector<T>::iterator pos ) const;
wrong ^^^^^
source to share
-
The first question is whether the iterator constant is meant to imply container-wide constants, or just the iterator constant.
Apparently it was decided that the latter is the correct approach. An iterator constant does not imply a container constant, it only implies the construction of container elements.
-
Since the beginning of time, the construction of an object and its symmetrical counterpart, the destruction of an object, have been considered meta-operations on the object itself. The object should always behave as mutable with respect to these operations, even if it was declared as
const
. It is for this reason that you can legally modify objectsconst
in your constructors and destructors. For this reason, you candelete
create an object of typeT
using a pointerconst T *
.
Given the resolution mentioned in 1, it becomes clear that 2 should be extended to iterators as well.
source to share