交错std :: map插入和迭代

时间:2016-08-07 06:15:53

标签: c++ c++11 iterator iteration stdvector

如果我像这样迭代std::map

typedef std::map<connection, connectionData> clist;
clist m_connections;

for (const auto itt : m_connections)
{
       connectionData outerPlayerData = itt .second;
// Do stuff 
}

并且代码中的某个地方m_connections不断被填充,这是否意味着迭代循环将永远运行?是否在增长 或者它会在这个时间点运行m_connections的大小以及在那个时间点的相关大小?

3 个答案:

答案 0 :(得分:2)

如果您继续在大于当前迭代位置的位置继续添加,它将永远迭代。元素不断添加,循环迭代考虑了map的当前状态。

Demo

int main() {
    // your code goes here
    map<int, int> m;
    m.insert(make_pair(10, 11));
    int i = 0;
    for(auto it : m){
        cout << it.second << endl;
        if(i++ == 0){ 
            m.insert(make_pair(15, 12));
        }
    }
    return 0;
}

输出为:

11
12

不是

11

答案 1 :(得分:1)

那么,查看std::map的迭代器失效规则,至少代码不会显示UB。

这为插入的任何内容留下了两种可能性:它会在当前迭代位置之前或之后插入到容器中。

如果在当前迭代点之后每次迭代可靠地插入至少一个新元素,则会得到一个无限循环,否则你将不会。

那么,新元素如何比较?

相关标准引用:

  

9 insertemplace成员不应影响迭代器和容器引用的有效性,擦除成员只能使迭代器和对擦除元素的引用无效。
  10关联容器迭代器的基本属性是它们以密钥的非降序迭代容器,其中非降序由用于构造它们的比较定义。对于任何两个可解除引用的迭代器ij,从ij的距离为正,value_comp(*j, *i) == false
  11对于具有唯一键的关联容器,更强的条件成立value_comp(*i, *j) != false

答案 2 :(得分:0)

在我看来这很危险。该程序可能会崩溃。我认为你正在使用多线程。一种是迭代地图,而另一种是添加到地图。 添加到地图可能会更改地图中的基础结构。当一个线程正在修改而另一个正在读取相同的结构时,这将是一个竞争条件。

@Saurav Sahu在您的情况下,根据您添加的值,可以在当前迭代器之前或之后添加新值。例如,如果在for循环中使用键9(&lt; 10)插入,它仍然输出11。