Чтение объекта из const unordered_map
Почему мне не разрешено читать объект из константы unordered_map?
const unordered_map<int, int> z;
int val = z[5]; // compile error
Ошибка под clang следующая:
error: no viable overloaded operator[] for type 'const
unordered_map<int, int>'
int val = z[5];
Учитывая, что эквивалентный код с помощью const vector
отлично работает, я несколько смущен, почему мы получаем это поведение.
Ответы
Ответ 1
Выражение z[5]
вызывает неконстантную функцию-член map.
Это потому, что карта operator[]
будет вставлять новый элемент, если ключ не найден, поэтому, очевидно, он должен быть не const.
При a vector
ничего не вставлено operator[]
, элемент должен существовать уже (или вы получаете поведение undefined, поэтому эквивалентный код будет обращаться к 6-му элементу пустого вектора, что не так!).
Для поиска ключа без добавления его используйте:
int val = 0;
auto it = z.find(5);
if (it != z.end())
val = it->second;
Ответ 2
Как уже сказал Джонатан, метод operator[]
является неконстантным, поскольку он может добавить значение по умолчанию, когда искомый элемент не найден.
С другой стороны, как подчеркнул Бенджамин в комментарии, метод at()
также доступен для const.
const unordered_map<int, int> z;
int val = z.at(5); // Success!
Недостатком является то, что когда искомого значения нет на карте, возникает исключение std::out_of_range
, поэтому им нужно управлять.