交错 std::map 插入和迭代

Interleaving std::map insertion and iteration

如果我像这样迭代 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 的大小和那个时间点的相关大小?

如果在大于当前迭代位置的位置不断添加,会一直迭代下去。元素不断添加,循环迭代考虑地图的当前状态。

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

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

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

好吧,看看 std::map 的迭代器失效规则,至少代码没有显示 UB。

这只为插入的任何内容留下两种可能性:它比您当前的迭代位置更早或更晚插入到容器中。

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

那么,新元素比较怎么样呢?

相关标准引用:

9 The insert and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.
10 The fundamental property of iterators of associative containers is that they iterate through the containers in the non-descending order of keys where non-descending is defined by the comparison that was used to construct them. For any two dereferenceable iterators i and j such that distance from i to j is positive, value_comp(*j, *i) == false
11 For associative containers with unique keys the stronger condition holds, value_comp(*i, *j) != false.