对unordered_map

时间:2017-06-17 02:15:08

标签: c++ c++14 unordered-map c++17

这是一段非常简单的代码:

#include <cstdio>
#include <unordered_map>

int main() {  
    std::unordered_map<int, int> m;
    m[1] = m.find(1) == m.end() ? 0 : 1;
    printf("%d\n", m[1]);
    return 0;
}

如果地图不包含1,请指定m[1]=0;否则m[1]=1。我尝试使用不同的gcc编译器here

gcc5.2总是输出1,gcc7.1总是输出0。

为什么这么不同?难道不总是0吗?我无法理解这种行为。编写这种逻辑最安全的方法是什么?

1 个答案:

答案 0 :(得分:26)

结果取决于编译器是否支持C ++ 2017。

根据C ++ 2017标准(5.18分配和复合赋值运算符)

  

1赋值运算符(=)和复合赋值运算符   所有组从右到左。所有都需要左侧可修改的左值   操作数并返回一个引用左操作数的左值。结果   在所有情况下,如果左操作数是位字段,则是位字段。在所有   在这种情况下,赋值在值的计算之后排序   左右操作数,以及之前的值计算   赋值表达式右操作数在左前排序   操作数。即可。关于一个不确定顺序的函数调用,   复合指派的操作是单一评估

另一方面,根据C ++ 2014标准(5.18分配和复合赋值运算符)

  

1赋值运算符(=)和复合赋值运算符   所有组从右到左。所有都需要左侧可修改的左值   操作数并返回一个引用左操作数的左值。结果   在所有情况下,如果左操作数是位字段,则是位字段。在所有   在这种情况下,赋值在值的计算之后排序   左右操作数,以及之前的值计算   赋值表达式。关于不确定的顺序   函数调用,复合赋值的操作是单一的   评价。

正如您所看到的,C ++ 2014标准的引用中没有粗体语句。

因此,您不应该依赖左右操作数的评估顺序。