[英]Assignment (operator =) invalidates iterators for containers
我有這樣的代碼:
std::vector<int> v1 = { 1, 2, 3, 4 };
std::vector<int> v2 = { 7, 8, 9, 10 };
std::vector<int>::iterator it = std::next(v1.begin());
v1 = v2;
int test = *it;
std::cout << test;
上面的代碼將引發錯誤:迭代器不可取消。
但是,如果我用list替換vector如下:
std::list<int> v1 = { 1, 2, 3, 4 };
std::list<int> v2 = { 7, 8, 9, 10 };
std::list<int>::iterator it = std::next(v1.begin());
v1 = v2;
int test = *it;
std::cout << test;
該代碼按預期運行,沒有錯誤。
從迭代器失效規則和std :: list :: operator = ,我被告知, 在調用operator =之后,與該容器相關的所有迭代器,引用和指針都將失效,但最終迭代器除外。 但是,為什么上面帶有std :: list的代碼有效? 我是否誤解了一些必不可少的東西?
當迭代器失效時,對其取消引用是未定義的行為。 因此,就規范而言,您觀察到的任何行為都是無關緊要的。 根據您的期望,“工作”是允許的行為。
FWIW(不多,tbh),我希望實現std::list
賦值運算符等效於以下內容:
list& operator=(list const& rhs) {
if (this == &rhs)
return *this;
auto lhs_i = begin();
auto rhs_i = rhs.begin();
// write over the elements in any currently existing nodes, this
// avoids any unnecessary allocations
while (lhs_i != end() && rhs_i != rhs.end()) {
*lhs_i++ = *rhs_i++;
}
// erase any extra elements if size() > rhs.size()
erase(lhs_i, end());
// push back additional elements if size() < rhs.size()
while (rhs_i != rhs.end()) {
push_back(*rhs_i++);
}
return *this;
}
如果是這樣,您可以看到,對於像您這樣的情況,列表都具有相同數量的元素,則不會創建或銷毀任何元素,因此您非常希望迭代器能夠繼續正常工作。 當然,這完全是推測,絕對不是您應該依賴的行為,因為即使您的實現是這種情況,他們也可以在下一個發行版中更改它,而無需另行通知。
這是未定義的行為,但是GCC具有調試容器來捕獲這種行為。
使用-D_GLIBCXX_DEBUG
啟用它:
int test = *it;
^~~~
/usr/local/include/c++/6.1.0/debug/safe_iterator.h:270:
Error: attempt to dereference a singular iterator.
Objects involved in the operation:
iterator "this" @ 0x0x7fff5f561e90 {
type = __gnu_debug::_Safe_iterator<std::__cxx1998::_List_iterator<int>, std::__debug::list<int, std::allocator<int> > > (mutable iterator);
state = singular;
references sequence with type 'std::__debug::list<int, std::allocator<int> >' @ 0x0x7fff5f561ef0
}
bash: line 7: 16071 Aborted (core dumped) ./a.out
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.