C ++ map访问丢弃限定符(const)

时间:2008-11-04 18:29:44

标签: c++ stl const maps

以下代码表示将地图作为const传递到operator[]方法会丢弃限定符:

#include <iostream>
#include <map>
#include <string>

using namespace std;

class MapWrapper {
public:
    const int &get_value(const int &key) const {
        return _map[key];
    }

private:
    map<int, int> _map;
};

int main() {
    MapWrapper mw;
    cout << mw.get_value(42) << endl;
    return 0;
}

这是因为地图访问中可能出现的分配吗?没有地图访问的函数可以声明为const吗?

MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers

5 个答案:

答案 0 :(得分:139)

std::map's operator [] is not declared as const, and cannot be due to its behavior:

  

T&安培; operator [](const Key&amp; key)

     

返回对映射到等效于key的键的值的引用,如果此类键尚不存在则执行插入。

因此,您的函数无法声明const,并使用地图的operator[]

std::map's find()功能允许您在不修改地图的情况下查找密钥。

find()会向iteratorconst_iterator返回包含密钥(.first)和值(.second)的std::pair

在C ++ 11中,您还可以将at()用于std::map。如果元素不存在,则该函数会抛出std::out_of_range异常,而不是operator []

答案 1 :(得分:10)

您无法在operator[]的地图上使用const因为该方法不是const,因为它允许您修改地图(您可以指定为_map[key]) 。请尝试使用find方法。

答案 2 :(得分:9)

由于operator[]没有const限定的重载,因此无法在const限定的函数中安全地使用它。这可能是因为当前的重载是为了返回和设置键值而建立的。

相反,您可以使用:

VALUE = map.find(KEY)->second;

或者,在C ++ 11中,您可以使用at()运算符:

VALUE = map.at(KEY);

答案 3 :(得分:7)

一些较新版本的GCC头文件(我机器上的4.1和4.2)具有非标准成员函数map :: at(),如果键不在地图中,则声明为const和throw std :: out_of_range。 / p>

const mapped_type& at(const key_type& __k) const

根据函数注释中的引用,似乎已将其建议为标准库中的新成员函数。

答案 4 :(得分:0)

首先,您不应该使用以_开头的符号,因为它们是为语言实现/编译器编写者保留的。对于某人的编译器来说,_map很容易成为语法错误,除了你自己,你没有人可以责备。

如果你想使用下划线,请把它放在最后,而不是开头。您可能犯了这个错误,因为您看到了一些Microsoft代码。记住,他们编写自己的编译器,因此他们可以逃脱它。即便如此,这也是一个坏主意。

operator []不仅返回引用,它实际上在地图中创建了条目。所以你不只是得到一个映射,如果没有,你就是在创建一个映射。那不是你想要的。