【问题标题】:Why does insert invalidate the std::set reverse iterator为什么插入使 std::set 反向迭代器无效
【发布时间】:2013-11-07 01:24:19
【问题描述】:

我的理解是关联容器的迭代器在插入或擦除期间不会失效(除非迭代器指向的节点被擦除)。但是在下面的程序中 插入似乎使迭代器无效。是不是我的理解错了?

typedef std::set<unsigned int> myset_t;

int main(int argc, char **argv)
{
    myset_t rs;
    myset_t::reverse_iterator rit;
    myset_t::reverse_iterator srit;
    int ii = 500;

    rs.insert(10);
    rs.insert(11);
    rs.insert(12);
    rs.insert(13);
    rs.insert(14);
    rs.insert(100000);
    rs.insert(102000);
    rs.insert(103000);

    rit = rs.rbegin();

    while(rit != rs.rend()) {
        srit = rit;
        if (*rit < 100000) {
            cout << "bailing here " << *rit << endl;
            return 0;
        } 
        rit++;
        cout << "Before erase " << *rit << endl;
        rs.erase(*srit);
        cout << "Before insert " << *rit << endl;
        rs.insert(ii);
        cout << "After insert " << *rit << endl;
        ii++;
    }
    cout << "Out of loop" << endl;
}
===

The output is 
Before erase 102000
Before insert 102000
After insert 14
bailing here 14

=====

【问题讨论】:

    标签: c++ stl set


    【解决方案1】:

    标准容器迭代器的承诺行为不适用于该容器的反向迭代器。

    反向迭代器实际上将正常(向前移动的)迭代器存储为成员,该迭代器在取消引用时位于反向迭代器所引用的元素之后。然后,当您取消引用反向迭代器时,本质上它会减少这个存储的普通迭代器的副本并取消引用它。所以这是一个问题:

    rit = rs.rbegin();     // rit stores rs.end()
    srit = rit;            // srit also stores rs.end()
    rit++;                 // rit stores a normal iterator pointing to the last element
    
    rs.erase(*srit);       // this deletes the last element, invalidating the normal
                           // iterator which is stored in rit. Funnily enough, the
                           // one stored in srit remains valid, but now *srit is a
                           // different value
    

    反向迭代器的行为是这样的,因为没有“before begin”迭代器。如果他们将迭代器存储到他们实际引用的元素中,rs.rend() 会存储什么?我确信有办法解决这个问题,但我想他们需要标准委员会不愿意做出的妥协。或者他们可能从未考虑过这个问题,或者认为它不够重要。

    【讨论】:

      猜你喜欢
      • 2013-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 2018-02-13
      • 1970-01-01
      • 2017-04-15
      • 1970-01-01
      相关资源
      最近更新 更多