c ++映射,使用扩展的for循环迭代时删除元素是否安全?

时间:2019-08-19 19:31:20

标签: c++ iterator

我有一个映射,其中键是整数,值是整数的向量。现在,这些向量包含一些重复的元素,我想将其删除。所以,我正在使用

sort(map.begin(),map.end())
map.erase(unique(map.begin(),map.end()),map.end());

一切正常。但是当我使用

这样的扩展for循环
for(auto i:map)

然后这不起作用,但是当我使用时它起作用:

for(auto i=map.begin();i!=map.end();i++)

下面是完整代码:

#define loopi(i,n) for(int i=0;i<n;i++)
map<int,vector<int>>m;
    m[0]={1,22,22,3};
    m[2]={2,1,11,11,1,6};
    m[5]={2,2,2,33,5};
    for(auto i:m){
        cout<<i.second.size()<<endl;
        sort(i.second.begin(),i.second.end());
        i.second.erase(unique(i.second.begin(),i.second.end()),i.second.end());
        cout<<i.second.size()<<endl;
        loopi(j,i.second.size()) cout<<i.second[j]<<" ";
        cout<<endl;
    }
    cout<<endl;
    for(auto i:m){
        cout<<i.second.size()<<endl;
        loopi(j,i.second.size()) cout<<i.second[j]<<" ";
        cout<<endl;
    }

我得到输出:

4
3
1 3 22 
6
4
1 2 6 11 
5
3
2 5 33 

4
1 22 22 3 
6
2 1 11 11 1 6 
5
2 2 2 33 5 

并使用它:

    for(auto i=m.begin();i!=m.end();i++){
        cout<<i->second.size()<<endl;
        sort(i->second.begin(),i->second.end());
        i->second.erase(unique(i->second.begin(),i->second.end()),i->second.end());
        cout<<i->second.size()<<endl;
        loopi(j,i->second.size()) cout<<i->second[j]<<" ";
        cout<<endl;
    }
    cout<<endl;
    for(auto i=m.begin();i!=m.end();i++){
        cout<<i->second.size()<<endl;
        loopi(j,i->second.size()) cout<<i->second[j]<<" ";
        cout<<endl;
    }

在这种情况下,我得到输出:

4
3
1 3 22 
6
4
1 2 6 11 
5
3
2 5 33 

3
1 3 22 
4
1 2 6 11 
3
2 5 33 

因此,在第一种情况下,它不会删除元素。

1 个答案:

答案 0 :(得分:1)

您的第一个解决方案执行相同的操作,但是对实际元素的副本执行后续操作。在for(auto i:m)中,ipair<int, vector<int>>,由于您没有将其作为参考(即for(auto& i : m)),因此您要在其中修改的vector该循环是您拥有的原始vector的副本。

您的第二个示例之所以有效,是因为您使用的是迭代器,该迭代器不会创建数据副本。