为什么 std::map 没有 const 访问器?

Why does std::map not have a const accessor?

提问人:Calder 提问时间:12/16/2012 更新时间:2/2/2013 访问量:6872

问:

std::map 上 [] 运算符的声明如下:

T& operator[] ( const key_type& x );

不是这样有什么原因吗?

T& operator[] ( const key_type& x );
const T& operator[] const ( const key_type& x );

因为每当您需要以 const 方法访问成员映射时,这都会非常有用。

C++ C++11 标准

评论

0赞 xtofl 12/19/2012
哇,伙计,你进入了每周的堆栈交换时事通讯:)
0赞 Calder 12/20/2012
呵呵,酷!你们有一些很棒的答案,谢谢!

答:

4赞 eduffy 12/16/2012 #1

因为 的语义是添加密钥,如果它不存在。operator[]

80赞 Luchian Grigore 12/16/2012 #2

operator[]在映射中,返回指定键处的值,或者为该键创建一个新的值初始化元素(如果该元素尚不存在),因此这是不可能的。

如果有重载,则添加元素将不起作用。operator[]const

这就回答了这个问题。选择:

对于 C++03 - 您可以使用迭代器(这些迭代器与 和 非耦合)。在 C++11 中,可以使用该方法。constconstfindat

6赞 NPE 12/16/2012 #3

如果密钥不存在,则 (non-) 创建密钥。constoperator[]

该运算符的版本(如果存在)必须具有不同的语义,因为它无法添加新键。const

我相信你会同意,具有明显不同语义的重载和非重载将是一罐蠕虫。因此,未提供任何版本。constconstconst

不过,有一个 const 成员,因此您可以在代码中使用它。find()

87赞 Stephan Dollberg 12/16/2012 #4

从 C++11 开始,它提供了 const 和非 const 访问。std::map::at

相反,如果元素不在映射中,它将引发异常。operator[]std::out_of_range

评论

5赞 xtofl 12/16/2012
这是一个很好的补充。
0赞 Calder 12/16/2012
这比写 foo.get(bar)->second 要好得多,谢谢!=)
6赞 boycy 12/17/2012
@Calder foo.find(bar)->second(不是'get')刚刚损坏,除非您已经知道 foo 有一个以 bar 为键的条目,否则它会返回一个不可取消引用的迭代器......
16赞 Cornstalks 12/16/2012 #5

这些答案是正确的,因为如果它不存在,则具有添加键的语义,但我想添加另一个视角:operator[]

请注意如何返回 .也就是说,它返回对与 关联的 的引用。但是,如果 中没有呢?我们应该返回什么?没有“空引用”这样的东西,抛出异常会很烦人。operator[]T&valuekeykeymap

这将是不的一个很好的理由。如果您无法向用户添加任何内容(因为运算符是),但他们正在查找不存在的项目,您会返回给用户什么?解决这个问题的一个好办法是没有 .operator[] constmapconstoperator[] const

评论

2赞 vobject 12/17/2012
好答案。也许 std::map 可以有一个 const 访问器,如果它返回一个迭代器而不是 T&。但我想这就是 std::map::find() 的用途。这在性能方面也会很糟糕,而且不是很直观。
0赞 Inverse 1/9/2013
为什么不只在 map 对象中有一个成员并返回对它的常量引用呢?T null_
1赞 Cornstalks 1/10/2013
@Inverse:那你是怎么初始化的?例如,如果是?null_Tint