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