C++ const std::map ссылка не компилируется
Есть ли причина, почему передача ссылки на std::map
как const вызывает разрыв оператора []? Я получаю эту ошибку компилятора (GCC 4.2), когда я использую const:
ошибка: нет совпадения для 'operator[]' в 'map [name]'
Вот прототип функции:
void func(const char ch, std::string &str, const std::map<std::string, std::string> &map);
И я должен отметить, что при удалении const
Ключевое слово перед std::map
,
Если меня правильно проинструктировали, оператор [] фактически вставит новую карту в карту, если не найдет ключ, что, конечно, объясняет, почему это происходит, но я не могу себе представить, что это когда-нибудь произойдет. приемлемое поведение.
Если есть лучший метод, например, использование find вместо [], я был бы признателен за это. Кажется, я не могу заставить работать тоже... Я получаю const несоответствующие ошибки итератора.
5 ответов
Да, вы не можете использовать operator[]
, использование find
, но обратите внимание, это возвращает const_iterator
вместо iterator
:
std::map<std::string, std::string>::const_iterator it;
it = map.find(name);
if(it != map.end()) {
std::string const& data = it->second;
// ...
}
Это как с указателями. Вы не можете назначить int const*
в int*
, Кроме того, вы не можете назначить const_iterator
в iterator
,
Когда вы используете оператор [], std::map ищет элемент с данным ключом. Если он не находит ничего, он создает его. Отсюда и проблема с конст.
Используйте метод поиска, и все будет в порядке.
Не могли бы вы опубликовать код о том, как вы пытаетесь использовать find()? Правильный путь будет:
if( map.find(name) != map.end() )
{
//...
}
Если вы используете C++ 11, std:: map:: at должен работать для вас.
Причина, по которой std::map::operator[] не работает, заключается в том, что в случае, если искомого ключа не существует на карте, он вставит новый элемент с использованием предоставленного ключа и вернет ссылку на него. (Подробности смотрите по ссылке). Это невозможно на const std::map.
Однако метод at генерирует исключение, если ключ не существует. При этом, вероятно, будет хорошей идеей проверить наличие ключа с помощью метода std:: map:: find, прежде чем пытаться получить доступ к элементу с помощью метода 'at'.
Для ваших "несоответствующих констант ошибок":
find () имеет две перегрузки:
iterator find ( const key_type& x );
const_iterator find ( const key_type& x ) const;
Я предполагаю, что вы получаете эту ошибку, потому что вы делаете что-то вроде назначения неконстантного итератора (слева) к результату find()
позвонить на const
карта:
iterator<...> myIter /* non-const */ = myConstMap.find(...)
Это может привести к ошибке, хотя, возможно, не той, которую вы видите.
Возможно потому, что в std::map нет оператора const []. Оператор [] добавит искомый элемент, если не найдет его. Поэтому используйте метод find(), если вы хотите искать без возможности добавления.