C++ 中的 const_iterator 和非常量迭代器有什么区别? 标准格式?
const_iterator
和 iterator
之间有什么区别?您会在哪里使用其中一个?
What is the difference between a const_iterator
and an iterator
and where would you use one over the other?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
const_iterator 不允许您更改它们指向的值,而常规迭代器则可以。
与 C++ 中的所有事物一样,总是更喜欢
const
,除非有充分的理由使用常规迭代器(即您想利用它们不是const
的事实来更改指向的值)。const_iterator
s don't allow you to change the values that they point to, regulariterator
s do.As with all things in C++, always prefer
const
, unless there's a good reason to use regular iterators (i.e. you want to use the fact that they're notconst
to change the pointed-to value).它们应该是不言自明的。 如果 iterator 指向 T 类型的元素,则 const_iterator 指向“const T”类型的元素。
它基本上等同于指针类型:
const 迭代器总是指向同一个元素,因此迭代器本身是const。 但它指向的元素不必是const,因此它指向的元素是可以改变的。
const_iterator 是一个指向 const 元素的迭代器,因此虽然迭代器本身可以更新(例如递增或递减),但它指向的元素不能更改。
They should pretty much be self-explanatory. If iterator points to an element of type T, then const_iterator points to an element of type 'const T'.
It's basically equivalent to the pointer types:
A const iterator always points to the same element, so the iterator itself is const. But the element it points to does not have to be const, so the element it points to can be changed.
A const_iterator is an iterator that points to a const element, so while the iterator itself can be updated (incremented or decremented, for example), the element it points to can not be changed.
最小可运行示例
非常量迭代器允许您修改它们指向的内容:
常量迭代器不允许:
如上所示,
v.begin()
是const
重载,并根据容器变量的 const 性返回iterator
或const_iterator
:弹出
const_iterator
的常见情况是在const
方法内使用this
时:const
使this
成为常量,从而使this->v
成为常量。您通常可以使用
auto
忘记它,但如果您开始传递这些迭代器,您将需要考虑它们的方法签名。与 const 和非常量非常相似,您可以轻松地从非常量转换为 const,但反之则不然:
使用哪一个:类似于
const int
与int
>:只要可以使用 const 迭代器(当您不需要用它们修改容器时),就更喜欢使用它们,以更好地记录您无需修改的阅读意图。Minimal runnable examples
Non-const iterators allow you to modify what they point to:
Const iterators don't:
As shown above,
v.begin()
isconst
overloaded, and returns eitheriterator
orconst_iterator
depending on the const-ness of the container variable:A common case where
const_iterator
pops up is whenthis
is used inside aconst
method:const
makesthis
const, which makesthis->v
const.You can usually forget about it with
auto
, but if you starting passing those iterators around, you will need to think about them for the method signatures.Much like const and non-const, you can convert easily from non-const to const, but not the other way around:
Which one to use: analogous to
const int
vsint
: prefer const iterators whenever you can use them (when you don't need to modify the container with them), to better document your intention of reading without modifying.不幸的是,STL 容器的许多方法都采用迭代器而不是const_iterators作为参数。 因此,如果你有一个 const_iterator,你不能说“在这个迭代器指向的元素之前插入一个元素”(在我看来,这样的说法在概念上并不是违反 const 的)。 如果您无论如何都想这样做,则必须使用 std::advance() 或 boost::next() 将其转换为非常量迭代器。 例如。 boost::next(container.begin(), std::distance(container.begin(), the_const_iterator_we_want_to_unconst))。 如果容器是std::list,则该调用的运行时间将为O(n)。
因此,当涉及到 STL 容器时,在任何“合乎逻辑”的地方添加 const 的通用规则就不那么通用了。
然而,boost 容器采用 const_iterators(例如 boost::unordered_map::erase())。 因此,当您使用 boost 容器时,您可以变得“非常激进”。 顺便问一下,有谁知道 STL 容器是否或何时会被修复?
Unfortunaty, a lot of the methods for the STL containers takes iterators instead of const_iterators as parameters. So if you have a const_iterator, you can't say "insert an element before the element that this iterator points to" (saying such a thing is not conceptually a const violation, in my opinion). If you want do that anyway, you have to convert it to a non-const iterator using std::advance() or boost::next(). Eg. boost::next(container.begin(), std::distance(container.begin(), the_const_iterator_we_want_to_unconst)). If container is a std::list, then the running time for that call will be O(n).
So the universal rule to add const wherever it is "logical" to do so, is less universal when it comes to STL containers.
However, boost containers take const_iterators (eg. boost::unordered_map::erase()). So when you use boost containers you can be "const agressive". By the way, do anyone know if or when the STL containers will be fixed?
尽可能使用const_iterator,当你别无选择时使用iterator。
Use const_iterator whenever you can, use iterator when you have no other choice.
(正如其他人所说) const_iterator 不允许您修改它指向的元素,这在 const 类方法内部很有用。 它还可以让您表达您的意图。
(as others have said) const_iterator doesn't allow you modify the elements to which it points, this is useful inside of const class methods. It also allows you to express your intent.
好吧,让我先用一个非常简单的例子来解释它,而不使用常量迭代器
考虑我们有随机整数集合“randomData”,
可以看出,在集合内写入/编辑数据时,使用了普通迭代器,但为了读取目的,使用了常量迭代器。 如果您尝试在第一个 for 循环中使用常量迭代器,您将收到错误。 作为经验法则,使用常量迭代器读取 collection 内的数据。
ok Let me explain it with very simple example first without using constant iterator
consider we have collection of random integers collection "randomData"
As can be seen for writing/editing data inside collection normal iterator is used but for reading purpose constant iterator has been used . If you try using constant iterator in first for loop you will get error . As a thumb rule use constant iterator to read data inside collection .