[英]Why does a push_back on an std::list change a reverse iterator initialized with rbegin?
[英]rbegin() in std::list is never equal to an iterator pointing into the list?
為什么以下代碼崩潰?
int main(int argc, const char * argv[]) {
std::list<int> aList={1,2,3,4,5};
std::list<int>::reverse_iterator i=aList.rbegin();
i++;
i++;
assert(*i==3);//assertion passes as expected
while (i!=aList.rbegin()) { //never becomes false
aList.pop_back(); //segmentation fault
}
assert(*(aList.rbegin())==3);
return 0;
}
我假設rbegin最終將等於i並停止循環; 但是沒有發生。
請注意,我確實按照以下變通辦法進行操作,但是仍然好奇,上述代碼首先出了什么問題
size_t differance =std::distance( aList.rbegin(),i);
while (differance >0) {
aList.pop_back();
differance--;
}
assert(*aList.rbegin()==3);
看起來一切都已反轉,增加反向迭代器會將其向后移動。
和pop_back()
將使最后一個元素的迭代器無效,因此循環中出現段錯誤。 您應該執行pop_front()
並檢查(i !=rend())
std::list::rbegin()
返回一個迭代器,該迭代器引用前哨列表末尾節點,但取消引用存儲在先前節點中的值(在您的情況下為5)。 此行為適用於std::list
任何反向迭代器:將其解引用時從中獲得值的節點反向迭代器是迭代器實際指向的節點之前的節點。
就迭代器引用哪個元素而言,將其可視化如下:
rend() <-------- rbegin()
| |
1 2 3 4 5 (end)
| |
begin() --------> end()
這意味着取消引用值3的迭代器實際上是在內部引用值為4的元素。當從列表中刪除值4時,存儲在i
的迭代器值將變為無效,這時您不能有關其行為的原因。 它可能(並且應該)不等於其他所有迭代器。
您可以通過在*i == 3
時*(i.base())
的值來驗證情況。 您將看到*(i.base()) == 4
。
因此,您的問題不是rbegin()
迭代器“永遠不等於指向列表的迭代器”,而是您要刪除迭代器內部指向的元素,然后嘗試將現在無效的迭代器與rbegin()
。
考慮使用aList.erase()
而不是循環。 由於您要從值為4的元素中刪除到數組的末尾,因此i.base()
已經為您提供了一個迭代器,您可以將其直接傳遞給aList.erase()
:
aList.erase(i.base(), aList.end());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.