从unordered_set中删除所有元素

时间:2017-09-12 13:21:42

标签: c++11 unordered-set

我已经完成了这篇文章Deleting elements from STL set while iterating

但是,我想了解为什么下面的代码会产生错误的结果。

int main() {
    unordered_set<int> adjacency;
    adjacency.insert(1);
    adjacency.insert(2);

    for (const auto& n : adjacency) {
        adjacency.erase(n);
    }

    cout <<"After removing all elements: " << endl;
    for (const auto& n : adjacency) {
        cout << n << " ";
    }
    cout << endl;

    return 0;
}

邻接包含1和2.通过for循环擦除所有元素后,它仍然包含元素1.为什么?

我正在使用下面的版本(2)擦除功能,因此规则&#34;版本(1)和(3)返回指向紧跟最后一个元素被删除后的位置的迭代器。&#34;不适用?

更新:不使用clear()的原因是它需要逐个删除元素以进行其他处理。

by position (1) 
iterator erase ( const_iterator position );
by key (2)  
size_type erase ( const key_type& k );
range (3)   
iterator erase ( const_iterator first, const_iterator last );

Version(2)返回已擦除的元素数,这些元素在unordered_set容器中(具有唯一值),如果存在值为k的元素(因此随后被擦除),则该值为1,否则为零。 / p>

版本(1)和(3)返回一个迭代器,指向紧跟最后一个元素删除后的位置。

谢谢!

2 个答案:

答案 0 :(得分:4)

基于范围的for循环使用引擎盖下的迭代器, 所以你写的内容会导致未定义的行为。

如果您需要处理所有元素,然后删除一些元素 根据某些标准,有一种方法可以做到这一点 适用于所有容器:

for(auto it = adjacency.begin(); it != adjacency.end();)
{
    Process(*it);
    if (Condition(*it))
        it = adjacency.erase(it);
    else
        ++it;
}

如果您需要处理所有项目,然后删除所有项目,请执行以下操作:

std::for_each(adjacency.begin(), adjacency.end(), &Process);
adjacency.clear();

答案 1 :(得分:2)

正如雷蒙德指出的那样,你正从自己的脚下拉出地毯。

#include <iostream>
#include <unordered_set>

using namespace std;

int main()
{
    typedef unordered_set<int> adjacency_t;
    typedef adjacency_t::iterator adjacencyIt_t;
    adjacency_t adjacency;
    adjacency.insert(1);
    adjacency.insert(2);

    cout <<"Before: " << endl;
    for (const auto& n : adjacency) {
        cout << n << " ";
    }
    cout << endl;

    for (adjacencyIt_t i = adjacency.begin(); i!=adjacency.end(); /*empty*/)
    {
        // Do some processing on *i here.
        adjacency.erase(i++); // Don't erase the old iterator before using it to move to the next in line.

    }

    cout <<"After removing all elements: " << endl;
    for (const auto& n : adjacency) {
        cout << n << " ";
    }
    cout << endl;

    return 0;
}