Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reading object from const unordered_map

Tags:

c++

Why am I not allowed to read an object from a constant unordered_map?

const unordered_map<int, int> z;
int val = z[5]; // compile error

The error under clang is the following:

error: no viable overloaded operator[] for type 'const
      unordered_map<int, int>'
                        int val = z[5];

Considering that the equivalent code using a const vector works fine I'm somewhat confused why we get this behavior.

like image 434
Voo Avatar asked Nov 13 '12 01:11

Voo


2 Answers

The expression z[5] calls a non-const member function of the map.

This is because a map's operator[] will insert a new element if the key isn't found, so obviously it has to be non-const.

For a vector nothing is inserted by operator[], the element must exist already (or you get undefined behaviour, so the equivalent code would access the 6th element of an empty vector, which is not fine!).

To lookup a key without adding it use:

int val = 0;
auto it = z.find(5);
if (it != z.end())
  val = it->second;
like image 74
Jonathan Wakely Avatar answered Oct 15 '22 11:10

Jonathan Wakely


As Jonathan already said, the operator[] method is non-const because it might add a default value when the item being looked up is not found.

On the other hand, as highlighted from Benjamin in a comment, the at() method is available for const as well.

const unordered_map<int, int> z;
int val = z.at(5); // Success!

The downside is that when the value being looked up is not in the map, a std::out_of_range exception is raised, so it has to be managed.

like image 21
hardsetting Avatar answered Oct 15 '22 13:10

hardsetting