[英]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);
}
但是,令我驚訝的是,這失敗了:顯然沒有為std::list
迭代器定義operator+
。
從那以后,我發現了另一個問題,並了解到刪除“從下面”迭代器的標准習慣用法更像
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使用僅定義增量和減量的BidirectionalIterator。 由於std :: list是一個鏈表,因此迭代器的實現一次只能移動一個節點。
該接口旨在確保您知道移動一個以上的元素並不像其他迭代器那樣簡單,就像從std :: vector返回的RandomAccessIterator一樣。
有關不同迭代器類型的定義,請參見http://en.cppreference.com/w/cpp/concept/Iterator 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.