Ste*_*mit 1 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);
}
Run Code Online (Sandbox Code Playgroud)
但我意识到,这段代码是错误的: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);
}
Run Code Online (Sandbox Code Playgroud)
但是,令我惊讶的是,这失败了:显然operator+没有为std::list迭代器定义.
我已经发现了另一个问题并且了解到删除"从下面"迭代器的标准习惯用法更像是
for(it = mylist.begin(); it != mylist.end(); ) {
if(some condition)
it = mylist.erase(it);
else ++it;
}
Run Code Online (Sandbox Code Playgroud)
我相信我也可以逃脱
for(it = mylist.begin(); it != mylist.end(); ) {
// ...
std::list<whatevertype>::iterator previt = it;
++it;
if(some condition)
mylist.erase(previt);
}
Run Code Online (Sandbox Code Playgroud)
但我的问题是,有operator+没有为这些迭代器定义的原因?
Yak*_*ont 10
他们对std迭代器和集合的一个规则是使昂贵的东西变得冗长.
在列表迭代器上,it+50花费O(50)时间.在向量迭代器上,it+50需要O(1)时间.所以它们+在向量迭代器(和其他随机访问迭代器)上实现,但在列表迭代器(以及其他较弱的迭代器)上实现.
std::next并且std::advance和std::prev能解决你的问题更容易:
auto previt = std::prev(it);
Run Code Online (Sandbox Code Playgroud)
要么
auto nextit = std::next(it);
Run Code Online (Sandbox Code Playgroud)
这些也需要计算,但因为它们是一个明确的函数调用,所以决定它们的价格昂贵是可以接受的.
除此之外,您还可以搜索对std::nextand的调用std::prev并获取迭代器操作; +严重超载,找到昂贵的电话很难.
请注意,std::basic_string它不遵循与其他std容器相同的约定.