簡體   English   中英

分配(operator =)使容器的迭代器無效

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM