从const unordered_map读取对象

Voo*_*Voo 17 c++

为什么我不允许从常量unordered_map中读取对象?

const unordered_map<int, int> z;
int val = z[5]; // compile error
Run Code Online (Sandbox Code Playgroud)

clang下的错误如下:

error: no viable overloaded operator[] for type 'const
      unordered_map<int, int>'
                        int val = z[5];
Run Code Online (Sandbox Code Playgroud)

考虑到使用一个const vector工作正常的等效代码我有点困惑为什么我们得到这种行为.

Jon*_*ely 26

该表达式z[5]调用映射的非const成员函数.

这是因为operator[]如果找不到键,map 会插入一个新元素,所以很明显它必须是非const的.

对于vector没有插入operator[]的元素,元素必须已经存在(或者你得到未定义的行为,所以等效代码将访问空向量的第6个元素,这不是很好!).

要在不添加密钥的情况下查找密钥,请使

int val = 0;
auto it = z.find(5);
if (it != z.end())
  val = it->second;
Run Code Online (Sandbox Code Playgroud)

  • 为了不那么冗长,你也可以使用`int val = z.at(5);` - 在这种情况下,如果键不在地图中,你将获得`std :: out_of_range`异常.当然,如果将它包围在try-catch块中,它也不会那么冗长. (13认同)

har*_*ing 8

正如Jonathan所说,该operator[]方法是非const的,因为它可能会在找不到项目时添加默认值.

另一方面,正如Benjamin在评论中强调的那样,该at()方法也适用于const.

const unordered_map<int, int> z;
int val = z.at(5); // Success!
Run Code Online (Sandbox Code Playgroud)

缺点是,当查找的值不在映射中时,std::out_of_range会引发异常,因此必须对其进行管理.