为什么我们不能为map提供一个不可变版本的operator[]
下面的代码工作正常:
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
The following code works fine :
std::map<int, int>& m = std::map<int, int>();
int i = m[0];
But not the following code :
// error C2678: binary '[' : no operator...
const std::map<int, int>& m = std::map<int, int>();
int i = m[0];
Most of the time, I prefer to make most of my stuff to become immutable, due to reason :
http://www.javapractices.com/topic/TopicAction.do?Id=29
I look at map source code. It has
mapped_type& operator[](const key_type& _Keyval)
Is there any reason, why std::map unable to provide
const mapped_type& operator[](const key_type& _Keyval) const
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
原因是
std::map
语义规定,如果您尝试访问不存在的键处的元素,则会使用默认构造的元素创建该键。换句话说,如果 int 尚不存在,m[0]
将在位置 0 创建一个 int。显然,这与 const 映射不兼容。你可以说“好吧,制作一个 const 版本的operator[]并且让它不这样做!”,但是有两个问题:语义上的差异不明显并且令人困惑,而且它是不清楚如果您确实尝试访问不存在的密钥(抛出异常?),会发生什么情况。
相反,您应该做的是使用地图上的
find()
方法,该方法将返回一个指向您要查找的键/值对的迭代器。查找与operator[]
完全相同,它可以在 const 映射上使用(在这种情况下返回 const 迭代器),并且它将返回end()
如果键不存在则迭代器。The reason is that
std::map
semantics state that if you try to access an element at a key that does not exist, the key is created with a default-constructed element. In other wordsm[0]
will create an int at location 0 if one does not already exist. Obviously, that is not compatible with a const map.You could say "well, make a const version of
operator[]
and have it not do that!", but there are two problems: the difference in semantics would be non-obvious and confusing, and it's not clear exactly what should happen if you do try to access a key that does not exist (throw an exception?).Instead, what you should do is use the
find()
method on the map, which will return an iterator pointing to the key/value pair you're looking for. The lookup is exactly as efficient asoperator[]
, it can be used on const maps (returning a const iterator in that case), and it will return theend()
iterator if the key does not exist.如果映射中不存在,operator[] 将创建该条目。如果该运算符是针对 const 映射实现的,则这是不可能的。这是C++ 编程语言中给出的解释:
operator[] will create the entry if it does not exist in the map. This is not possible if the operator is implemented for a const map. This is the explanation given in The C++ Programming Language:
它确实有一个不可变的版本,称为
find()
。It does have an immutable version, and it's called
find()
.如果没有找到键,operator[] 就会插入,因此它不能是 const 成员函数。
operator[] inserts if the key is not found, therefore it cannot be a const member function.