为什么 std::list 迭代器没有运算符+
Why no operator+ for std::list iterators?
我正要写这样的代码:
std::list<whatevertype> mylist;
// ...
std::list<whatevertype>::iterator it;
for(it = mylist.begin(); it != mylist.end(); ++it) {
// ...
if(some condition)
mylist.erase(it);
}
但我意识到,这段代码是错误的:mylist.erase(x)
将使迭代器it
无效,因此++it
可能会失败。
所以我尝试将其更改为
std::list<whatevertype>::iterator it;
std::list<whatevertype>::iterator nextit;
for(it = mylist.begin(); it != mylist.end(); it = nextit) {
// ...
nextit = it + 1;
if(some condition)
mylist.erase(it);
}
但是,令我惊讶的是,这失败了:显然operator+
没有为std::list
迭代器定义。
从那以后,我发现了另一个问题,并了解到删除迭代器"从下面出来"的标准习语更像
for(it = mylist.begin(); it != mylist.end(); ) {
if(some condition)
it = mylist.erase(it);
else ++it;
}
我相信我也可以侥幸逃脱
for(it = mylist.begin(); it != mylist.end(); ) {
// ...
std::list<whatevertype>::iterator previt = it;
++it;
if(some condition)
mylist.erase(previt);
}
但我的问题是,是否有理由没有为这些迭代器定义operator+
?
他们对 std 迭代器和集合的一个规则是使昂贵的东西变得冗长。
在列表迭代器上,it+50
需要 O(50( 时间。 在向量迭代器上,it+50
需要 O(1( 时间。 因此,他们在向量迭代器(和其他随机访问迭代器(上实现了+
,但没有在列表迭代器(和其他较弱的迭代器(上实现。
std::next
和std::advance
和std::prev
可以更轻松地解决您的问题:
auto previt = std::prev(it);
或
auto nextit = std::next(it);
这些也需要计数,但由于它们是显式函数调用,因此决定它们昂贵是可以接受的。
除此之外,您还可以搜索对std::next
和std::prev
的调用,并获得迭代器操作; +
严重超载,很难找到昂贵的电话。
请注意,std::basic_string
不遵循与其他std
容器相同的约定。
所有迭代器都缺少+
。std::list
迭代器缺少它。
这是因为列表迭代器在随机访问时效率极低。因此,使随机访问变得容易是一个坏主意。
您可以使用std::advance
.它使你更明显地在列表中移动,一次一个元素。
std::list 使用仅定义递增和递减的双向迭代器。由于 std::list 是一个链表,迭代器的实现一次只能移动一个节点。
该界面旨在确保您知道移动多个元素不是像其他迭代器(如从 std::vector 返回的 RandomAccessIterator(那样的简单操作。
有关不同迭代器类型的定义,请参阅 http://en.cppreference.com/w/cpp/concept/Iterator。
- 迭代器类的重载前缀增量运算符会引发分段错误
- 了解运算符重载和迭代器,为什么它会打印出"wrhrwwr"?
- 映射迭代器与运算符不匹配
- 提供运算符+或运算符到双向迭代器有什么缺点吗?
- 无法使用迭代器查找类对象。(二进制 '==': 'userInfo' 不定义此运算符)
- 迭代器和无符号整数的重载 + 运算符
- 迭代器的范围 TS 和 C++20 概念是否需要能够使用"运算符>"?
- C++ 使用矢量迭代器时的运算符优先级
- 在 c++ 迭代器中,我应该同时定义运算符== 和运算符!=吗?
- 迭代器关系运算符出错(带单独链接和迭代器的自定义哈希表)
- 为什么 std::list 迭代器没有运算符+
- 如何让迭代器使用赋值运算符对列表进行操作
- 迭代器和增量运算符
- 为什么我们要把 :: (范围重新定位运算符)放在迭代器之前
- Gnu 的 <Iterator>reverse_iterator::运算符>和代理迭代器
- 输入迭代器 - 星号和后缀运算符
- 后缀运算符链表泛型节点迭代器
- 在自定义双链接列表中的自定义迭代器的取消运算符,找不到二进制操作员
- 与运算符"!="不匹配(c++ 迭代器)
- 在地图迭代器上不支持非仿制地图上的平等运算符(==)