[try Beta version]
Not logged in

 
Why is std::map::operator[] w/o const version?

Dec 2, 2011 at 8:30am
Hi all,
I see there is no const operator[] method for both std::map and boost::unordered_map. Why is that? I'm almost done with a tree-like structure of maps and wrote adapter to have such functionality... I wonder if I made a pit for me or others to fall into or what?
Dec 2, 2011 at 8:43am
operator[] returns a reference and if the element can't be found it will create it. If it was const there would be no other way than throwing an exception because it can't create new elements.

In C++11 there is the function std::map::at that will always throw if the element can't be found and it has both const and non-const versions.
Dec 2, 2011 at 8:44am
See documentation:

A call to this function (operator[]) is equivalent to:
(*((this->insert(make_pair(x,T()))).first)).second
Dec 2, 2011 at 9:19am
If you need it, you can use map::find.
Dec 2, 2011 at 9:52am
So, presuming that I don't even plan avoiding exceptions, to
me it's just logical that maps need also a const version of
operator[] ...
Dec 2, 2011 at 10:05am
Simple way:
 
const SomeClass & o = map.find(/*something*/)->second;

Safe way:
1
2
3
4
auto it = map.find(/*something*/);

if(it != map.end())
	o = it->second;


That's complicated?
Dec 2, 2011 at 10:48am
Depends...
Suppose you have a whole tree of maps, which store some
configuration or other data. You'd access that tree like
this:
myMapsTree("branch1")("branch2")(..)["data keyX"]

The point is: sometimes it will be by design that certain
keys will be already stored, but the access permission to
tree will be RO. So, how does this seem over there?
Dec 2, 2011 at 11:15am
And what happens when there's no entry with that key in the map? Normally, it would cause it to be inserted, but a const version of operator[] can't do that. That leaves throwing an exception, resulting in entirely different behavior of the two versions. Certainly not desirable.
And like Peter87 already said, now there's at(), which has a const and non-const version - and both behave the same.
Dec 2, 2011 at 11:20am
This kind of code is ugly using any kind of access. I can't imagine a situation where you would actually write this (and not make a function to map the "path" on the tree to it's value).

But using find isn't THAT verbose:

1
2
3
4
auto it = map.find("value1")->second;
it = it->second->find("value2")->second;
it = it->second->find("value3")->second;
// .. 
Dec 2, 2011 at 12:10pm
Actually true about access: would be ugly to use full path
through operator()s. So I myself confused tree population
for test purposes, which happen easily with those operators,
with RO access?!

Since the new map::at() may throw, I guess it's all merely
about avoidance of confusion. But is it so likely to not
know what kind of an object/ref is used: const or RW?
Could Athar elaborate on why not to allow operator[] const
to throw if it can't find the key?
Topic archived. No new replies allowed.