如何在std::map的值上使用基于范围的for循环
How do you use a range-based for loop on the values of a std::map?
我正试图使用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()有两个版本,为什么没有[]的两个版本?
map::operator[]
在未找到键的情况下将新元素插入映射中,因此它不能是const
,也不能在const
map
上调用。
请改用m.at(2)
。
operator[]
将执行两件事中的一件。如果元素存在,它会在该位置找到元素并返回。如果该位置没有元素,它会对其进行值初始化,然后返回。
因此,它既不是逻辑上的,也不是程序上的const
。
虽然您可能会说"但是有一个元素2",但操作的const
程度仅取决于参数的类型,而不是参数的值。并且m[int]
不能保证在那里有一个有效的元素。
要解决此问题,可以将m[2]
替换为m.find(2)->second
。如果映射中缺少2
,则执行未定义的行为,但如果存在2
,则其计算结果与m[2]
相同。相反,如果2
作为密钥存在,m.at(2)
将再次执行相同的操作,如果不存在,则抛出异常。
顺便说一句,当处理这样的问题时,试着把代码分解成更小的部分。m[2];
本身在一行上将无法编译。事实上,错误消息告诉你它找不到operator[]
——这可能会给你一个错误的线索。
您的映射m
被声明为const
,这意味着您只能在其上调用const
函数。
std:map::operator[]
不是这样的函数,因为如果找不到指定的键,它将修改映射。
你需要的是std::map::at
,也就是const
,所以你可以在你的const
地图上称它。
相关文章:
- 基于范围循环到旧编译器的旧样式
- 带有自定义对象的C 范围循环
- 为什么编译器不优化集合元素上的空范围循环?
- 迭代在包含向量的vor in for for范围循环中迭代
- 我们可以在范围循环中使用引用(而不是指针)上的删除
- 将自适应阈值应用于范围函数 opencv c++
- 如何实现我的自定义范围循环
- C++范围循环
- GCC 4.4 不实现 C++11 范围循环.它还支持哪些其他范围循环语法
- 嵌套c++11范围循环,用于查找组合
- 范围循环中的访问索引
- 对于不可复制类型的范围循环,是否可能
- "继续"使用标志作用于哪个循环?
- 我的范围循环出现逻辑错误
- 如何在我的类上允许范围循环
- c++的范围循环比递减循环快
- 通过范围循环从指针容器中获取取消引用元素的引用
- 为什么在这种情况下PPL明显慢于顺序循环和OpenMP
- c++ 11:为什么这个范围循环会使FPS下降35
- 带有自定义类的范围循环(矢量的简单版本<string>,使用分配器)