Следующий код говорит, что передача карты as const
в operator[]
метод отбрасывает квалификаторы:
#include <iostream>
#include <map>
#include <string>
using namespace std;
class MapWrapper {
public:
const int &get_value(const int &key) const {
return _map[key];
}
private:
map<int, int> _map;
};
int main() {
MapWrapper mw;
cout << mw.get_value(42) << endl;
return 0;
}
Это из-за возможного выделения, которое происходит при доступе к карте? Нельзя ли объявить функции с доступом к карте как const?
MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers
Ответы:
std::map
'soperator []
не объявлен какconst
и не может быть обусловлен его поведением:В результате ваша функция не может быть объявлена
const
и использовать картуoperator[]
.std::map
«Sfind()
функция позволяет искать ключ , не изменяя карту.find()
возвращает объектiterator
илиconst_iterator
объект,std::pair
содержащий как ключ (.first
), так и значение (.second
).В C ++ 11 вы также можете использовать
at()
дляstd::map
. Если элемент не существует, функция выдаетstd::out_of_range
исключение, в отличие отoperator []
.источник
operator[]
(напримерfoo[bar] = baz
) и rvalueoperator[]
(напримерx = foo[bar]
) - последнее, безусловно, может быть const.Поскольку у
operator[]
него нет перегрузки с квалификацией const, его нельзя безопасно использовать в функции с квалификацией const. Вероятно, это связано с тем, что текущая перегрузка была создана с целью как возврата, так и установки значений ключей.Вместо этого вы можете использовать:
или, в C ++ 11, вы можете использовать
at()
оператор:источник
map.find(KEY)->second;
небезопасно, если значения карты являются строками. Когда KEY не найден, он печатает мусор.Вы не можете использовать
operator[]
на карте,const
поскольку этот метод не является,const
поскольку он позволяет вам изменять карту (вы можете назначить_map[key]
).find
Вместо этого попробуйте использовать этот метод.источник
Некоторые более новые версии заголовков GCC (4.1 и 4.2 на моей машине) имеют нестандартные функции-члены map :: at (), которые объявлены как const и выбрасывают std :: out_of_range, если ключ отсутствует на карте.
Из ссылки в комментарии к функции видно, что это было предложено в качестве новой функции-члена в стандартной библиотеке.
источник
Во-первых, вы не должны использовать символы, начинающиеся с _, потому что они зарезервированы для реализации языка / средства записи компилятора. Было бы очень легко, если бы _map стал синтаксической ошибкой в чьем-то компиляторе, и вам было бы некого винить, кроме себя.
Если вы хотите использовать подчеркивание, ставьте его в конце, а не в начале. Вы, вероятно, сделали эту ошибку, потому что видели, как это делает код Microsoft. Помните, что они пишут свой собственный компилятор, так что им это может сойти с рук. Тем не менее, это плохая идея.
оператор [] не только возвращает ссылку, он фактически создает запись на карте. Таким образом, вы не просто получаете отображение, если его нет, вы его создаете. Это не то, что вы хотели.
источник
_
просто неверна. Идентификаторы, начинающиеся с двух подчеркиваний (__example
) или идентификаторы, начинающиеся с одного подчеркивания и заглавной буквы (_Example
), зарезервированы._example
не зарезервировано.