为什么我们在C++标准中没有'const iterator',而是const_iterator?

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

为什么要引入特殊类型 const_iterator

为什么不使一些迭代器内部可变,并使用标准 C++ const iterator

有没有讨论过const iterator

iterator 概念上是线性 space 上的一个位置。 space 中的每个位置都有一个对象。

const iterator确实存在。这是一个始终指向同一位置的迭代器。例如,你不能做 i++。即使不能更改指向的位置,也可以更改存储在该位置的对象:例如*i=10

A const_iterator should be read iterator to const...: 这与 const iterator 相反,你可以更改指向的位置,执行 i++ 是允许的,但是您永远无法更改指向的值:*i=10 不允许。

所以你有 4 个版本:iterator、const iterator、const_iterator 和 const const_iterator!

由于指针是迭代器的特例,让我们看一下这个例子:

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

发生什么事了?我们有指向非常量数据的常量指针。但是我们需要指向常量数据的非常量指针。明显的解决方案是:

using const_float_ptr = const float *;

这里是附加的const_iterator类型。迭代器的问题通常是相同的:const iteratorconst_iterator 具有不同的含义,并且在返回 const 对象 by value 之上在 C++ 中实际上是无用的你不能强制它只分配给 const 对象。

迭代器只是指针,抽象掉了一些杂乱的细节,如果允许编译器插入此类符号,则有可能插入调试信息。

因此,重要的是要考虑将 CV 限定符应用于指针的不同方式,以及这些方式与我们处理直接值的方式有何不同。

例如,在 C++ 中,以下类型声明是不等价的:

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

在C++迭代器方面,const iterator可以认为等同于我上面展示的int * const ptr3声明:指向的数据可以自由操作,但指针本身不能变了。 const_iterator,反过来等价于ptr2,意思是数据不能被修改,但是指针可以指向别的东西。假设的 const const_iterator 类似于 ptr4,既不允许更改数据也不允许更改指针本身。