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

下面的代码说明将映射作为 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
56281 次浏览

你不能使用 operator[]的地图是 const,因为该方法不是 const,因为它允许你修改地图(你可以分配给 _map[key])。尝试使用 find方法代替。

std::mapoperator []没有被声明为 const,并且不能由于它的行为:

操作员[](const 键和键)

返回对映射到与键等效的键的值的引用,如果该键不存在,则执行插入操作。

因此,您的函数不能声明为 const,并使用映射的 operator[]

std::mapfind() 函数允许您在不修改映射的情况下查找键。

find() iteratorconst_iterator返回给同时包含键(.first)和值(.second)的 std::pair

在 C + + 11中,还可以对 std::map使用 at()。如果元素不存在,函数将抛出 std::out_of_range异常,这与 operator []不同。

一些较新版本的 GCC 头(在我的机器上是4.1和4.2)有非标准的成员函数 map: : at () ,这些函数声明为 const,如果键不在 map 中,则抛出 std: : out _ of _ range。

const mapped_type& at(const key_type& __k) const

从函数注释中的引用来看,这似乎已经被建议作为标准库中的一个新成员函数。

首先,不应该使用以 _ 开头的符号,因为它们是保留给语言实现/编译器编写器的。_ map 很容易成为某人编译器上的语法错误,这只能怪你自己。

如果要使用下划线,请将其放在结尾,而不是开头。您可能犯了这个错误,因为您看到了一些 Microsoft 代码正在这样做。请记住,他们编写自己的编译器,所以他们可能能够摆脱它。即便如此,这也不是个好主意。

操作符[]不仅返回引用,而且实际上在映射中创建条目。所以你不仅仅是得到一个映射,如果没有映射,你就是在创建一个映射。这不是你的本意。

因为 operator[]没有一个 const 限定的重载,所以它不能安全地用在 const 限定的函数中。这可能是因为当前重载的目标是返回和设置键值。

相反,你可以使用:

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

或者,在 C + + 11中,你可以使用 at()操作符:

VALUE = map.at(KEY);