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

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?
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.
See documentation:

A call to this function (operator[]) is equivalent to:
(*((this->insert(make_pair(x,T()))).first)).second
If you need it, you can use map::find.
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[] ...
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?
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?
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.
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;
// .. 
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.