为什么我无法在 const std::map 中使用运算符[]访问元素?

问题描述 投票:0回答:4

我尝试使用

operator[]
访问
const map
中的元素,但是这个方法失败了。我也尝试使用
at()
来做同样的事情。这次成功了。但是,我找不到任何有关使用
at()
访问
const map
中的元素的参考。
at()
map
中新增的功能吗?我在哪里可以找到有关此的更多信息?非常感谢!

示例如下:

#include <iostream>
#include <map>

int main()
{
    std::map<int, char> A;
    A[1] = 'b';
    A[3] = 'c';

    const std::map<int, char> B = A;

    std::cout << B.at(3) << std::endl; // it works
    std::cout << B[3] << std::endl;    // it does not work
}

对于使用

B[3]
,编译时返回以下错误:

t01.cpp:14:错误:传递“const” std::map > >’ 作为 ‘_Tp& 的 ‘this’ 参数 std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [其中 _Key = int, _Tp = char, _Compare = std::less, _Alloc = std::allocator >]’ 丢弃限定符

使用的编译器是g++ 4.2.1

c++ dictionary constants std stdmap
4个回答
161
投票

at()
是 C++11 中
std::map
的新方法。

如果具有给定键的元素不存在,则不会像

operator[]
那样插入新的默认构造元素,而是抛出
std::out_of_range
异常。 (这类似于
at()
对于
deque
vector
的行为。)

由于这种行为,

const
at()
重载是有意义的,这与
operator[]
总是有可能改变地图不同。


39
投票

如果

map
中不存在某个元素,
operator []
将会添加它——这显然不能在
const
映射中工作,因此 C++ 没有定义
const
版本的运算符。这是编译器类型检查器防止潜在运行时错误的一个很好的例子。

在您的情况下,您需要使用

find
来代替,它将 only 返回一个(迭代器)元素(如果存在),它永远不会修改
map
。如果某个项目不存在,它将返回一个迭代器到地图的
end()

at
不存在,甚至不应该编译。也许这是一个“编译器扩展”(= C++0x 中的一个 bug 新内容)。


5
投票
如果给定的键不存在,[] 运算符将在映射中创建一个“新条目”。因此它可能会改变地图。

请参阅此链接

这让我很惊讶,但是 STL 映射没有

3
投票
索引运算符。也就是说,

B[3]

不能是只读的。来自手册:
由于operator[]可能会向映射中插入一个新元素,因此它不可能是const成员函数。

我不知道at()

© www.soinside.com 2019 - 2024. All rights reserved.