C++ STL中const_iterator和非const迭代器之间有什么区别?

Kon*_*rad 118 c++ iterator stl const

a const_iterator和an 之间的区别是什么iterator?你在哪一个使用另一个?

Dom*_*ger 104

const_iterators不允许你改变他们指向的值,常规iterators.

与C++中的所有内容一样,总是更喜欢const,除非有充分的理由使用常规迭代器(即您希望使用它们不会const更改指向值的事实).

  • 在一个完美的世界中,情况就是如此.但是使用C++ const只能和编写代码的人一样好:( (7认同)
  • 它确实有合法的用途,比如在const类中缓存长计算的结果.另一方面,这几乎是我在近二十年的C++开发中使用变量的唯一时间. (6认同)
  • 更像是一个强大的黑客。在我见过的所有使用 'mutable' 关键字的例子中,除了一个都是一个准确的指标,表明代码写得不好,需要 mutable 作为绕过缺陷的黑客。 (2认同)

jal*_*alf 38

它们几乎应该是不言自明的.如果迭代器指向类型为T的元素,则const_iterator指向"const T"类型的元素.

它基本上等同于指针类型:

T* // A non-const iterator to a non-const element. Corresponds to std::vector<T>::iterator
T* const // A const iterator to a non-const element. Corresponds to const std::vector<T>::iterator
const T* // A non-const iterator to a const element. Corresponds to std::vector<T>::const_iterator
Run Code Online (Sandbox Code Playgroud)

const迭代器总是指向同一个元素,因此迭代器本身就是const.但它指向的元素不一定是const,所以它指向的元素可以改变.const_iterator是指向const元素的迭代器,因此虽然可以更新迭代器本身(例如递增或递减),但它指向的元素不能更改.

  • 啊,我明白了.是的,我错过了缺少的下划线. (4认同)
  • @JohnDibling Upvoted用于解释`const iterater`和`const_iterator`之间的微妙之处. (3认同)
  • “常量迭代器总是指向同一个元素”,这是不正确的。 (2认同)
  • 怎么会这样?请注意缺少的下划线.我将const std :: vector <T> :: iterator类型的变量与std :: vector <T> :: const_iterator进行对比.在前一种情况下,迭代器本身是const,因此无法修改,但它引用的元素可以自由修改. (2认同)

Mag*_*rmo 7

不幸的是,STL容器的很多方法都使用迭代器而不是const_iterators作为参数.所以,如果你有一个const_iterator,你不能说"在这个迭代器指向的元素之前插入一个元素"(在我看来,这样的事情在概念上不是一个const违规).如果你想要这样做,你必须使用std :: advance()boost :: next()将它转换为非const迭代器.例如.boost :: next(container.begin(),std :: distance(container.begin(),the_const_iterator_we_want_to_unconst)).如果containerstd :: list,那么该调用的运行时间将为O(n).

因此,在STL容器方面,将const添加到任何"逻辑"的通用规则都不太通用.

但是,boost容器需要const_iterators(例如boost :: unordered_map :: erase()).因此,当您使用增强容器时,您可以"持久".顺便问一下,有人知道STL容器是否或何时会被修复?


Cir*_*四事件 6

最小的可运行示例

非常量迭代器允许您修改它们指向的内容:

std::vector<int> v{0};
std::vector<int>::iterator it = v.begin();
*it = 1;
assert(v[0] == 1);
Run Code Online (Sandbox Code Playgroud)

Const 迭代器不会:

const std::vector<int> v{0};
std::vector<int>::const_iterator cit = v.begin();
// Compile time error: cannot modify container with const_iterator.
//*cit = 1;
Run Code Online (Sandbox Code Playgroud)

如上所示,v.begin()const重载,并根据容器变量的常量性返回iterator或返回const_iterator

const_iterator弹出的常见情况是 whenthisconst方法中使用:

class C {
    public:
        std::vector<int> v;
        void f() const {
            std::vector<int>::const_iterator it = this->v.begin();
        }
        void g(std::vector<int>::const_iterator& it) {}
};
Run Code Online (Sandbox Code Playgroud)

const使thisconst,这使this->vconst。

您通常可以使用 忘记它auto,但是如果您开始传递这些迭代器,您将需要为方法签名考虑它们。

就像 const 和非常量一样,您可以轻松地从非常量转换为 const,但不能反过来:

std::vector<int> v{0};
std::vector<int>::iterator it = v.begin();

// non-const to const.
std::vector<int>::const_iterator cit = it;

// Compile time error: cannot modify container with const_iterator.
//*cit = 1;

// Compile time error: no conversion from const to no-const.
//it = ci1;
Run Code Online (Sandbox Code Playgroud)

使用哪一个:类似于const intvs int:只要你可以使用 const 迭代器(当你不需要用它们修改容器时),就更喜欢它们,以更好地记录你的阅读意图而无需修改。


Nav*_*een 5

尽可能使用const_iterator,在没有其他选择时使用迭代器.