我尝试使用std::map::operator[]
使用基于范围的for循环迭代std::map
的值,但以下内容不会编译:
#include <iostream> // cout, endl
#include <map> // map
#include <set> // set
using namespace std;
int main () {
using namespace std;
const map<int, set<int>> m {{2, {201, 202}}, {3, {301, 302}}};
for (int v : m[2])
cout << v << endl;
return 0;
}
这是编译器的错误消息:
Test.c++:18:19: error: no viable overloaded operator[] for type 'const map<int, set<int> >'
for (int v : m[2])
后续问题是,鉴于at()有两个版本,为什么没有两个版本的[]?
答案 0 :(得分:5)
map::operator[]
会在地图中插入新元素,因此无法const
,并且无法在const
{{1}上调用}。
改为使用map
。
答案 1 :(得分:3)
operator[]
会做两件事之一。它将在该位置找到该元素(如果存在)并将其返回。如果该位置没有元素,它将对其进行值初始化,然后将其返回。
因此,它既不是逻辑上也不是编程const
。
虽然您可能会说“但是有一个元素2”,但操作的const
依赖于参数的 types ,而不是参数的值。并且m[int]
不保证在那里有有效的元素。
要解决此问题,您可以将m[2]
替换为m.find(2)->second
。如果地图中缺少2
,则会执行未定义的行为,但如果2
存在,则会评估与m[2]
相同的内容。如果m.at(2)
作为键存在,2
将再次执行相同的操作,如果不存在则抛出异常。
顺便说一句,在处理此类问题时,请尝试将代码分解为更小的部分。 m[2];
单独在一行上将无法编译。事实上,错误消息告诉您它找不到operator[]
- 这可能会让您知道错误。
答案 2 :(得分:1)
您的地图m
已声明为const
,这意味着您只能在其上调用const
个功能。
std:map::operator[]
不是这样的函数,因为如果找不到指定的键,它将修改映射。
您需要的是std::map::at
const
,因此您可以在const
地图上调用它。