Почему у нас не может быть неизменной версии оператора [] для карты - PullRequest
4 голосов
/ 17 марта 2010

Следующий код работает нормально:

std::map<int, int>& m = std::map<int, int>();
int i = m[0];

Но не следующий код:

// error C2678: binary '[' : no operator...
const std::map<int, int>& m = std::map<int, int>();
int i = m[0];

В большинстве случаев я предпочитаю делать большинство своих вещей неизменяемыми по причине:

http://www.javapractices.com/topic/TopicAction.do?Id=29

Я смотрю на исходный код карты. Имеет

mapped_type& operator[](const key_type& _Keyval)

Есть ли причина, по которой std :: map не может предоставить

const mapped_type& operator[](const key_type& _Keyval) const

Ответы [ 4 ]

6 голосов
/ 17 марта 2010

Причина в том, что семантика std::map утверждает, что если вы пытаетесь получить доступ к элементу по ключу, который не существует, ключ создается с помощью элемента, созданного по умолчанию. Другими словами m[0] создаст int в местоположении 0, если он еще не существует. Очевидно, что это не совместимо с константной картой.

Вы могли бы сказать «ну, сделайте константную версию operator[] и не делайте этого!», Но есть две проблемы: разница в семантике будет неочевидной и сбивающей с толку, и не совсем понятно, что должно произойти, если вы попытаетесь получить доступ к ключу, который не существует (сгенерировать исключение?).

Вместо этого вам следует использовать метод find() на карте, который вернет итератор, указывающий на искомую пару ключ / значение. Поиск точно такой же эффективный, как и operator[], он может использоваться на константных картах (в этом случае возвращая константный итератор), и он вернет итератор end(), если ключ не существует.

4 голосов
/ 17 марта 2010

оператор [] создаст запись, если она не существует на карте. Это невозможно, если оператор реализован для константной карты. Это объяснение дано в языке программирования C ++ :

Подписка на карту добавляет значение по умолчанию элемент, когда ключ не найден. Поэтому для константных отображений не существует версии operator []. Кроме того, подписка может быть используется только если mapped_type (значение тип) имеет значение по умолчанию. Если программист просто хочет увидеть, если ключ присутствует, операция find () (§17.4.1.6) может использоваться, чтобы найти ключ без изменения карты.

2 голосов
/ 17 марта 2010

Он имеет неизменяемую версию и называется find().

1 голос
/ 17 марта 2010

оператор [] вставляет, если ключ не найден, поэтому он не может быть функцией-константой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...