为什么使用 != 来比较循环条件中的迭代器
Why using != to compare iterator in loop condition
在很多关于迭代向量的例子中,我注意到经常使用不等于运算符来检查循环是否已经到达向量的末端。通常,我在循环条件中使用低于运算符。因此,我想知道,选择 !=
的理由是什么?
示例:
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto iter = vec.begin(); iter != vec.end(); iter++) {
std::cout << *iter << " ";
}
因为并非所有迭代器都支持排序,但都可以在 O(1) 中比较所有迭代器是否相等。
例如,关联(有序)容器使用双向迭代器,定义为 (cppreference):
template<class I>
concept bidirectional_iterator =
std::forward_iterator<I> &&
std::derived_from</*ITER_CONCEPT*/<I>, std::bidirectional_iterator_tag> &&
requires(I i) {
{ --i } -> std::same_as<I&>;
{ i-- } -> std::same_as<I>;
};
std::forward_iterator
只能取消引用、复制、==
和递增。
另一方面,std::vector
使用的随机访问迭代器需要 std::totally_ordered<I>
。因此,在您的情况下,您可以编写 iter < vec.end();
,但代码将变得不那么通用。只要您不在循环体中递增迭代器,您无论如何都是安全的。
据我了解,
iterator
在 STL 中有一个实现,使您能够“迭代”元素。使用它们,程序员不必编写移动到下一个元素的逻辑,具体取决于它在其中实现的数据结构。
也就是说,元素并不总是按顺序存储在内存中。因此,与索引相比,它们不能仅仅被比较为小于或大于。
对于矢量,具体来说,您可以选择在比较元素位置时使用索引。但同样不能与其他 DS 自信地说。
因此,在您的问题中,迭代器的实现可以通过比较是否到达最后一个元素来跨越所有元素。
在很多关于迭代向量的例子中,我注意到经常使用不等于运算符来检查循环是否已经到达向量的末端。通常,我在循环条件中使用低于运算符。因此,我想知道,选择 !=
的理由是什么?
示例:
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto iter = vec.begin(); iter != vec.end(); iter++) {
std::cout << *iter << " ";
}
因为并非所有迭代器都支持排序,但都可以在 O(1) 中比较所有迭代器是否相等。
例如,关联(有序)容器使用双向迭代器,定义为 (cppreference):
template<class I>
concept bidirectional_iterator =
std::forward_iterator<I> &&
std::derived_from</*ITER_CONCEPT*/<I>, std::bidirectional_iterator_tag> &&
requires(I i) {
{ --i } -> std::same_as<I&>;
{ i-- } -> std::same_as<I>;
};
std::forward_iterator
只能取消引用、复制、==
和递增。
另一方面,std::vector
使用的随机访问迭代器需要 std::totally_ordered<I>
。因此,在您的情况下,您可以编写 iter < vec.end();
,但代码将变得不那么通用。只要您不在循环体中递增迭代器,您无论如何都是安全的。
据我了解,
iterator
在 STL 中有一个实现,使您能够“迭代”元素。使用它们,程序员不必编写移动到下一个元素的逻辑,具体取决于它在其中实现的数据结构。
也就是说,元素并不总是按顺序存储在内存中。因此,与索引相比,它们不能仅仅被比较为小于或大于。
对于矢量,具体来说,您可以选择在比较元素位置时使用索引。但同样不能与其他 DS 自信地说。
因此,在您的问题中,迭代器的实现可以通过比较是否到达最后一个元素来跨越所有元素。