为什么我们不能为map设置operator []的不可变版本

时间:2010-03-17 03:36:39

标签: c++ stl

以下代码可以正常使用:

std::map<int, int>& m = std::map<int, int>();
int i = m[0];

但不是以下代码:

// error C2678: binary '[' : no operator...
const std::map<int, int>& m = std::map<int, int>();
int i = m[0];

大多数时候,由于理由,我更喜欢让我的大部分内容变得一成不变:

http://www.javapractices.com/topic/TopicAction.do?Id=29

我看一下地图源代码。它有

mapped_type& operator[](const key_type& _Keyval)

有什么理由,为什么std :: map无法提供

const mapped_type& operator[](const key_type& _Keyval) const

4 个答案:

答案 0 :(得分:6)

原因是std::map语义声明如果您尝试访问不存在的键的元素,则使用默认构造的元素创建键。换句话说,m[0]将在位置0处创建一个int(如果尚不存在)。显然,这与const map不兼容。

你可以说“好吧,制作operator[]的const版本并让它不要那样做!”但是有两个问题:语义上的差异是不明显和令人困惑的,而且还不清楚如果您尝试访问不存在的密钥(抛出异常?),究竟会发生什么。

相反,你应该做的是在地图上使用find()方法,它将返回一个指向你正在寻找的键/值对的迭代器。查找与operator[]完全一样有效,它可以在const映射上使用(在这种情况下返回一个const迭代器),如果键不存在,它将返回end()迭代器。

答案 1 :(得分:4)

如果地图中不存在,

operator []将创建该条目。如果为const映射实现运算符,则无法执行此操作。这是The C++ Programming Language中给出的解释:

  

订阅地图会添加默认值   找不到密钥时的元素。   因此,const映射没有operator []的版本。   此外,下标也可以   仅在mapped_type(值   type)有一个默认值。如果   程序员只是想看看是否   key存在,find()操作   (§17.4.1.6)可用于定位a   键而不修改地图。

答案 2 :(得分:2)

它确实有一个不可变版本,它被称为find()

答案 3 :(得分:1)

如果找不到键,则运行

operator [],因此它不能是const成员函数。