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.

+3


source to share


2 answers


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 ^^^^^

      

+8


source


  • 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 objects const

    in your constructors and destructors. For this reason, you can delete

    create an object of type T

    using a pointer const T *

    .



Given the resolution mentioned in 1, it becomes clear that 2 should be extended to iterators as well.

0


source







All Articles