C ++ const映射元素访问


100

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

示例如下:

#include <iostream>
#include <map>

using namespace std;

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

        const map<int, char> B = A;

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

}

对于使用“ B [3]”,它在编译过程中返回以下错误:

t01.cpp:14:错误:将'const std :: map,std :: allocator>>'作为'_Tp&std :: map <_Key,_Tp,_Compare,_Alloc> :: operator [](' const _Key&)[with _Key = int,_Tp = char,_Compare = std :: less,_Alloc = std :: allocator>]'丢弃限定符

使用的编译器是g ++ 4.2.1

Answers:


124

at()std::mapC ++ 11中的一种新方法。

operator[]它不会引发带有std::out_of_range异常的新异常,而不会像具有给定键的元素那样插入新的默认构造元素。(这类似于at()for deque和的行为vector。)

由于存在这种行为,因此有的const重载是有意义的,与之at()不同的是,operator[]它总是有可能更改地图。


是否可以让“ at”返回默认值而不是抛出异常?
user1202136 2012年

at()在VS2013中使用一个设置为使用VS2010工具包的项目。我以为那意味着我没有使用C ++ 11 ...但是它可以编译... ??
thomthom 2013年

1
我只需要评论说,忽略const运算符[]是没有意义的,它也可能为未映射的元素引发异常,而不是更改映射。
斯宾塞

@Spencer如果operator []的const和非const重载具有不同的效果,这将是令人惊讶的。通常,我们期望如果将程序中的某些非常量对象或引用设为const,则只要编译,程序将继续以相同的方式运行。仅允许非const重载引发异常可能导致直到运行时才捕获错误。
布莱恩

@Brian您的意思是说“仅允许const重载引发异常”吗?
斯宾塞

33

如果元素中不存在mapoperator []则会添加该元素–显然在const地图中无法使用,因此C ++不会定义const运算符的版本。这是防止潜在运行时错误的编译器类型检查器的一个很好的示例。

在您的情况下,您需要使用find,它只会返回(迭代器)元素(如果存在),而不会修改map。如果某个项目不存在,则会将迭代器返回到地图的end()

at不存在,甚至不应该编译。也许这是一个“编译器扩展程序”(=一个错误 C ++ 0x中的新功能)。


C ++标准是否禁止实现在库类中定义其他非标准成员函数?
蒂姆·马丁

@Tim我相信接口是固定的,是的。
康拉德·鲁道夫

4

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

请参阅此链接


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.