c++ 中的 [] 操作后 unordered_map 元素消失

Alb*_*ieu 1 c++

在下面的 C++ 代码中,unordered_map 元素意外消失的行为让我很困惑。在第一个for循环中,我将每个元素的剩余部分存储在timemoduled by 60 中,并将其计数存储在 中unordered_map<int, int> m,在第二个 for循环中,我将内容打印在 中m,到目前为止,一切似乎都正常。 cout如下

0:1
39:1
23:1
18:1
44:1
59:1
12:1
38:1
56:2
17:1
37:1
24:1
58:1
Run Code Online (Sandbox Code Playgroud)

然而在第三个for循环中,它只打印了 中的部分元素m

0:1
39:1
58:1
0:1
Run Code Online (Sandbox Code Playgroud)

看来很多元素都mn += m[remainder]*m[60-remainder];操作删除了。我对这种行为感到很困惑,你能理解这是怎么回事吗?实在是太迷茫了。

#include <iostream>
#include<unordered_map>
#include<vector>
using namespace std;
int main() {
    vector<int> time ({418,204,77,278,239,457,284,263,372,279,476,416,360,18});
    int n =0;
    unordered_map<int,int> m; // <remiander,cnt>
    for (auto t:time)
        m[t%60]++;
    for (auto [remainder,cnt]:m)
         cout<<remainder<<":"<<cnt<<endl;
    cout<<endl;
    for (auto [remainder,cnt]:m){
        cout<<remainder<<":"<<cnt<<endl;

        if (remainder==0 || remainder==30)
            n += cnt*(cnt-1)/2;
        else
            n += m[remainder]*m[60-remainder];
        }
}
Run Code Online (Sandbox Code Playgroud)

Sam*_*hik 7

第三个循环[]在循环内使用运算符。

for (auto [remainder,cnt]:m){

   // ...

   n += m[remainder]*m[60-remainder];
Run Code Online (Sandbox Code Playgroud)

unordered_map[]如果导致重新散列,则会使所有现有迭代器无效。这包括范围迭代期间使用的隐式迭代器。

如图所示,m[remainder]无法导致重新散列,因为它只能访问无序映射中的现有值,但对于 来说则不然m[60-remainder],从而导致未定义的行为。

您只需要删除[]运算符的这种用法并将其替换为等效的find()(当然,end()如果返回值,则正确处理该值)。