Почему я не могу передать структуру const map функции в c ++? - PullRequest
10 голосов
/ 02 мая 2010

Я попытался передать const с вектором, он работает: Пример:

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

}

Но при попытке с картой это не так:

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

Интересно, почему это не так.

Ответы [ 3 ]

25 голосов
/ 02 мая 2010

map::operator[] немного странно. Это делает это:

  1. Ищите ключ.
  2. Если найден, верните его.
  3. Если нет, вставьте его и создайте по умолчанию его связанное значение.
  4. Затем верните ссылку на новое значение.

Шаг 3 несовместим с const Несс. Вместо двух по-разному работающих operator[] перегрузок язык заставляет вас использовать map::find для const объектов.

С другой стороны, можно утверждать, что бы map::operator[] const сделал, если аргумента нет на карте? Бросить исключение? Неопределенное поведение? (В конце концов, это то, что vector::operator[] делает с индексом, выходящим за пределы.) В любом случае проблему можно избежать только с небольшим неудобством для нас.

my_map.find(key) возвращает my_map.end(), если key не найден.

5 голосов
/ 02 мая 2010

std::map::operator[] вставляет элемент, созданный по умолчанию, если запрошенный элемент отсутствует на карте. Это , поэтому это не постоянная функция-член . Вместо этого вы можете использовать std::map::find, но обязательно проверьте возвращаемый им итератор.

2 голосов
/ 02 мая 2010

Я полагаю, что это потому, что [] в карте не const, так как создает новую пару со значением по умолчанию, если вы обращаетесь к несуществующей. Попробуйте

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