Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么没有操作员+;对于std::列表迭代器?_C++_Iterator_Erase - Fatal编程技术网

C++ 为什么没有操作员+;对于std::列表迭代器?

C++ 为什么没有操作员+;对于std::列表迭代器?,c++,iterator,erase,C++,Iterator,Erase,我正要写这样的代码: std::list<whatevertype> mylist; // ... std::list<whatevertype>::iterator it; for(it = mylist.begin(); it != mylist.end(); ++it) { // ... if(some condition) mylist.erase(it); } 但是,令我惊讶的是,这失败了:显然,operator+没有为s

我正要写这样的代码:

std::list<whatevertype> mylist;

// ...

std::list<whatevertype>::iterator it;

for(it = mylist.begin(); it != mylist.end(); ++it) {
    // ...
    if(some condition)
        mylist.erase(it);
}
但是,令我惊讶的是,这失败了:显然,
operator+
没有为
std::list
迭代器定义

从那以后,我发现并了解到迭代器中删除“out from under”的标准习惯用法更像

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);
}
for(it=mylist.begin();it!=mylist.end();){
// ...
std::list::迭代器previt=it;
++它;
如果(某些条件)
mylist.erase(previt);
}

但我的问题是,
操作符+
没有为这些迭代器定义有什么原因吗?

他们对std迭代器和集合的一个规则是让昂贵的东西变得冗长

在列表迭代器上,
it+50
需要O(50)个时间。在向量迭代器上,
it+50
需要O(1)个时间。因此,他们在向量迭代器(和其他随机访问迭代器)上实现了
+
,但在列表迭代器(和其他较弱的迭代器)上实现了
+

std::next
std::advance
std::prev
可以更轻松地解决您的问题:

auto previt = std::prev(it);

这些也需要计算,但因为它们是显式函数调用,所以决定它们的开销是可以接受的

除此之外,您还可以搜索对
std::next
std::prev
的调用,并获取迭代器操作<代码>+严重超载,很难找到昂贵的调用


请注意,
std::basic_string
与其他
std
容器不遵循相同的约定。

并非所有迭代器都缺少
+
std::list
迭代器缺少它

这是因为列表迭代器在随机访问时效率极低。因此,使随机访问变得容易是一个坏主意


你可以用。更明显的是,您一次只在列表中移动一个元素。

std::list使用只定义递增和递减的双向运算符。由于std::list是一个链表,迭代器的实现一次只能移动一个节点

该接口的设计目的是确保您知道,通过多个元素移动并不像其他迭代器(如从std::vector返回的RandomAccessIterator)那样是一个简单的操作


有关不同迭代器类型的定义,请参阅。

通过使用,您可以获得等效的功能。这可能是比手动循环更好的习惯用法。“使昂贵的东西变得冗长”。啊哈。这是关键。谢谢。问题标题根据您的第一句话进行了更新,谢谢。
auto previt = std::prev(it);
auto nextit = std::next(it);