user188276
user188276

Reputation:

Why can't I use operator[] with a const std::map?

I tried to pass const with vector it works: Ex:

void damn(const vector <bool> &bb)
{
    for (int i = 0; i < bb.size(); i++)
        cout << bb[i] << endl;
}

But when trying with map, it does not:

void pas(const map <string, float> &mm)
{
    cout << mm["a"];
    cout << mm["b"];
}

I wonder why it doesn't.

Upvotes: 11

Views: 3065

Answers (3)

Draco Ater
Draco Ater

Reputation: 21226

I believe that it is because [] in map isn't const, as it creates new pair with default value, if you address to nonexisting one. Try

void pas(const map <string, float> &mm)
{
    cout<<mm.find("a")->second;
    cout<<mm.find("b")->second;
}

Upvotes: 3

Potatoswatter
Potatoswatter

Reputation: 137780

map::operator[] is a little odd. It does this:

  1. Look for the key.
  2. If found, return it.
  3. If not, insert it and default-construct its associated value.
  4. Then return a reference to the new value.

Step 3 is incompatible with constness. Rather than have two differently-functioning operator[] overloads, the language forces you to use map::find for const objects.

Alternately, one could argue, what would map::operator[] const do if the argument is not in the map? Throw an exception? Undefined behavior? (After all, that's what vector::operator[] does with an index out of bounds.) In any case, the problem is avoided with only a small inconvenience to us.

my_map.find(key) returns my_map.end() if the key is not found.

Upvotes: 27

bk1e
bk1e

Reputation: 24328

std::map::operator[] inserts a default-constructed element if the requested element is not in the map. This is why it is not a const member function. You can use std::map::find instead, but be sure to check the iterator it returns.

Upvotes: 6

Related Questions