std :: vector的一个小问题,并在循环时更改集合

Ath*_*ase 9 c++ stdvector

此循环在运行时更改迭代器:

std::vector<int> c;
c.push_back(1);
c.push_back(2);

std::vector<int>::iterator iter    = c.begin();
std::vector<int>::iterator endIter = c.end();

while( iter != endIter )
{
    std::cout << (*iter) << std::endl;
    iter = c.erase(iter);
}
Run Code Online (Sandbox Code Playgroud)

它不起作用,因为:

对迭代元素及其与容器末尾之间的元素的迭代器和引用无效.过去的迭代器也是无效的

我怎样才能重写这个(不使用std::list和使用while循环)?

顺便说一句,我知道auto自C++ 11以来已经实现了.使用它为什么有益?

Cas*_*sey 22

只是不要缓存将失效的结束迭代器:

while( iter != c.end() )
{
    std::cout << (*iter) << std::endl;
    iter = c.erase(iter);
}
Run Code Online (Sandbox Code Playgroud)

或打印后清除矢量:

for(const auto& i : c) {
    std::cout << i << std::endl;
}
c.clear();
Run Code Online (Sandbox Code Playgroud)

  • 在多线程上下文中使用`vector`的另一个好习惯是获取锁,然后`swap(cumulative_vector,local_vector)`然后放弃锁.然后处理`local_vector`中捕获的值并丢弃它. (2认同)

Bet*_*eta 12

擦除元素会发生变化end().改变循环:

while( iter != c.end())
Run Code Online (Sandbox Code Playgroud)


AnT*_*AnT 7

  • 将其改写为

    while( iter != c.end() )
    {
        std::cout << (*iter) << std::endl;
        iter = c.erase(iter);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    并且代码将不再依赖任何可能无效的迭代器,

要么

  • 在每次无效操作后,"刷新"任何可能无效的迭代器

    while( iter != endIter )
    {
        std::cout << (*iter) << std::endl;
        iter = c.erase(iter);
        endIter = c.end();
    }
    
    Run Code Online (Sandbox Code Playgroud)

这些是通常在这种情况下使用的两种通用方法.