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