Why was a special type const_iterator
introduced?
Why not make some of the iterator internals mutable, and go with standard C++ const iterator
?
Was const iterator
ever discussed?
As pointer is a special case for iterator let's look on this example:
using float_ptr = float *;
float f = 0;
const float_ptr ptr = &f;
*ptr = 1.0; // fine changes variable f
ptr = nullptr; // fails, ptr is const
What happened? We have constant pointer to non-const data. But we need non-const pointer to const data. Obvious solution is:
using const_float_ptr = const float *;
here it is additional const_iterator
type. Problem for iterators in general is the same: const iterator
would have different meaning than const_iterator
and on top of that returning const object by value is practically useless in C++ as you cannot enforce it to be assigned only to const object.
An iterator
is conceptualy a location on a linear space. At each position in this space is located an object.
const iterator
s do exist. This an iterator that always point to the same location. You cannot do i++
for example. Even if you can not change the pointed location, you can change the object stored at that location: *i=10
for example
A const_iterator
should be read iterator to const...: this is the opposite of a const iterator
, you can change the pointed location, performing i++
is alowed, but you can never change the pointed value: *i=10
not allowed.
So you have 4 versions: iterator, const iterator, const_iterator, and const const_iterator!
Iterators are just Pointers, with some of their messy details abstracted away, and with the potential to have Debug information inserted if the compiler is permitted to insert such symbols.
As a result, it's important to think about the different ways that CV-qualifiers can be applied to Pointers, and how those ways differ from how we handle direct values.
For example, in C++, the following type declarations are NOT equivalent:
//Gonna leak lots of memory, don't worry about that for now
int * ptr = new int(1);
*ptr = 2;
ptr = new int(3);
int const* ptr2 = new int(4);
//*ptr2 = 5;//Not permitted, is a pointer-to-const, meaning the data it points to is immutable
ptr2 = new int(6);
ptr2 = ptr;
*ptr = 4;
//*ptr2 = 5;//immutability of data is enforced by the alias, not by the underlying data.
//ptr can still modify its own data, but ptr2 may not, even if it's the same data.
int * const ptr3 = new int(7);
*ptr3 = 8;
//ptr3 = new int(9);//Not permitted, is a const-pointer, meaning the pointer itself is immutable
//Note that the data being pointed to is NOT immutable, and can be freely altered
int const* const ptr4 = new int(10);
//*ptr4 = 11;//Not permitted, data pointed to is immutable
ptr4 = new int(12);//Not permitted, pointer is immutable
In terms of C++ iterators, const iterator
can be thought of as being equivalent to the int * const ptr3
declaration I showed above: the data pointed at can be freely manipulated, but the pointer itself cannot be changed. const_iterator
, conversely, is equivalent to ptr2
, meaning the data cannot be modified, but the pointer can be made to point at something else. A hypothetical const const_iterator
would be like ptr4
, permitting neither the data to change nor the pointer itself to change.
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.