简体   繁体   中英

Why we don't have 'const iterator' in the C++ standard, but const_iterator?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM