28

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

const unordered_map<int, int> z;
int val = z[5]; // compile error

clang下的错误如下:

error: no viable overloaded operator[] for type 'const
      unordered_map<int, int>'
                        int val = z[5];

考虑到使用 a 的等效代码可以const vector正常工作,我有点困惑为什么我们会得到这种行为。

4

2 回答 2

37

该表达式z[5]调用映射的非常量成员函数。

这是因为operator[]如果找不到键,映射将插入一个新元素,所以显然它必须是非常量的。

对于由vector插入的无operator[],该元素必须已经存在(否则您会得到未定义的行为,因此等效代码将访问空向量的第 6 个元素,这不好!)。

要查找密钥而不添加它,请使用:

int val = 0;
auto it = z.find(5);
if (it != z.end())
  val = it->second;
于 2012-11-13T01:36:00.960 回答
19

正如 Jonathan 已经说过的,该operator[]方法是非常量的,因为它可能会在未找到要查找的项目时添加默认值。

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

const unordered_map<int, int> z;
int val = z.at(5); // Success!

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

于 2017-08-07T14:19:36.890 回答