你如何在std :: map的值上使用基于范围的for循环?

时间:2015-02-27 01:23:15

标签: c++ c++11 stl

我尝试使用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()有两个版本,为什么没有两个版本的[]?

3 个答案:

答案 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地图上调用它。