Почему std :: map operator [] создает объект, если ключ не существует?

Я почти уверен, что где-то уже видел этот вопрос (comp.lang.c ++? Google, похоже, не нашел его там), но быстрый поиск здесь, похоже, не нашел его, так что вот он:

Почему оператор std :: map [] создает объект, если ключ не существует? Я не знаю, но для меня это кажется нелогичным, если сравнивать с большинством других операторов operator [] (например, std :: vector), где, если вы используете его, вы должны быть уверены, что индекс существует. Мне интересно, в чем причина реализации такого поведения в std :: map. Как я уже сказал, не было бы более интуитивно понятным действовать больше как индекс в векторе и сбой (ну, я думаю, неопределенное поведение) при доступе с недопустимым ключом?

Уточняю свой вопрос после просмотра ответов:

Хорошо, пока я получил много ответов, в которых говорилось, что в основном это дешево, так почему бы и нет, или что-то подобное. Я полностью согласен с этим, но почему бы не использовать для этого специальную функцию (я думаю, что в одном из комментариев говорилось, что в java нет оператора [] и функция называется put)? Я хочу сказать, почему оператор карты [] не работает как вектор? Если я использую operator [] для индекса вне диапазона вектора, я бы не хотел, чтобы он вставлял элемент , даже если он был дешевым, потому что это, вероятно, означает ошибку в моем коде. Я хочу сказать, почему с картой не то же самое. Я имею в виду, что для меня использование operator [] на карте означало бы: я знаю, что этот ключ уже существует (по какой-то причине я просто вставил его, у меня где-то есть избыточность, что угодно). Я думаю, так было бы более интуитивно.

Тем не менее, каковы преимущества выполнения текущего поведения с помощью operator [] (и только для этого я согласен с тем, что должна присутствовать функция с текущим поведением, а не operator [])? Может быть, это даст более четкий код? Я не знаю.

Другой ответ заключался в том, что он уже существовал таким образом, так почему бы не сохранить его, но тогда, возможно, когда они (те, которые были до stl) решат реализовать его таким образом, они обнаружили, что это дает преимущество или что-то в этом роде? Итак, мой вопрос в основном таков: почему я решил реализовать это таким образом, имея в виду некоторую несогласованность с другим оператором []. Какую пользу это дает?

Спасибо


person n1ckp    schedule 28.10.2009    source источник
comment
Для std :: vector флажок operator [] не установлен. Если вы попытаетесь получить доступ за пределами диапазона вектора, он с радостью вернет ссылку на недопустимый объект. Если вам нужна проверка, используйте метод at (). С другой стороны, std :: map не может этого сделать. Для работы с картой проще всего использовать метод find ().   -  person Martin York    schedule 28.10.2009
comment
Не гарантируется, что флажок std :: vector ‹› operator [] будет снят, его просто не требуется проверять.   -  person David Thornley    schedule 28.10.2009
comment
@ Дэвид Торнли: Спасибо, я этого не знал.   -  person n1ckp    schedule 28.10.2009
comment
Я просто хотел бы, чтобы у них была const версия оператора подписки, я готов заплатить цену исключения, чтобы действительно избежать использования map::find + map::end.   -  person Matthieu M.    schedule 29.10.2009
comment
@MatthieuM. согласовано. Хотя вместо этого вы можете использовать map::count.   -  person anilbey    schedule 27.08.2019
comment
Да, это одна из самых тупых функций STL. Большинство из нас думает о [] как об операции чтения, но она также используется для записи, возвращая неконстантную ссылку (которую вы затем можете присвоить). Вы не хотите, чтобы ссылка была недействительной, потому что люди обычно стреляют себе в ногу. Одним из способов обойти это (как указывает Клатчко) было бы, чтобы оператор [] генерировал исключение. Это был бы мой предпочтительный дизайн, но STL, похоже, не любит исключения. Это то, что делает Python (и ему даже не нужно беспокоиться о недействительных ссылках), и это просто имеет смысл (TM).   -  person allyourcode    schedule 02.06.2021


Ответы (12)


Поскольку operator[] возвращает ссылку на само значение, и поэтому единственный способ указать на проблему - это вызвать исключение (и в целом STL редко генерирует исключения).

Если вам не нравится такое поведение, вы можете использовать вместо него map::find. Он возвращает итератор вместо значения. Это позволяет ему возвращать специальный итератор, когда значение не найдено (он возвращает map::end), но также требует, чтобы вы разыменовали итератор, чтобы получить значение.

person R Samuel Klatchko    schedule 28.10.2009
comment
но разве вектор не возвращает ссылку? какая здесь разница? Извините, я не знаком с внутренним std :: map, так что, возможно, это очевидно из внутреннего. - person n1ckp; 28.10.2009
comment
Доступ к вектору за пределами с помощью [] является неопределенным поведением. Думаю, в этом случае map может вызвать какое-то неопределенное поведение, но вам это действительно нравится? С помощью вектора легко узнать, действителен ли индекс, с помощью карты - нет (вы можете сначала вызвать find, и в этом случае было бы бессмысленно вызывать [], поскольку вы уже должны были найти элемент, который вы ищем). - person UncleBens; 28.10.2009
comment
@ n1ck: std :: vector вернет недопустимую ссылку (потому что это легко сделать). std :: map не имеет простого способа вернуть ссылку. - person Martin York; 28.10.2009
comment
@UncleBens: да, думаю, то, что вы говорите, имеет смысл. Если бы оператор [] работал так, как я нашел бы более интуитивно понятным, это было бы, по сути, всего лишь находкой. Спасибо, я этого не осознавал. И все же мне не нравится, как это работает. Я знаю, что мне не нужно использовать его, если он мне не нравится, но я задал этот вопрос, потому что я просто заменил вектор картой, рассчитывая на то, что компилятор найдет мне ошибки, и я получил ошибку времени выполнения из-за это поведение. Думаю, это то, что я получаю, если рассчитываю на то, что компилятор найдет мои ошибки, когда я мог бы сделать лучше; o) - person n1ckp; 28.10.2009
comment
Традиционно интерфейс для карт (на всех языках, а не только на C ++) позволяет вам писать что-то вроде map[key] = value;, и карта заменяет существующее значение или при необходимости вставляет новое. Это давняя конвенция, поэтому неудивительно, что std::map ей следует. Однако, поскольку operator[] не может сказать, будет ли ссылка, которую он должен вернуть, будет использоваться слева от operator=, он всегда должен предполагать худшее и, следовательно, вставлять новый элемент. - person Pavel Minaev; 28.10.2009
comment
@Pavel Minaev: Спасибо, я не знал этого другого языка до того, как C ++ реализовал его таким образом. Любой пример? - person n1ckp; 28.10.2009
comment
C #, VB, Delphi, Python, Ruby, Eiffel, JavaScript, Lua относятся к числу тех, которые имеют конкретную нотацию [] или точный эквивалент (хотя на всех этих языках карта может различать получение значения через [] и присвоение [], поэтому этой проблемы там нет). В Java нет [], но Map.put имеет аналогичную семантику вставки или замены. На самом деле, полный список, вероятно, был бы старым на несколько страниц - это очень старое соглашение. Эта конкретная бородавка с инициализацией по умолчанию специфична для C ++ только потому, что нет хорошего способа отличить присваивание. - person Pavel Minaev; 28.10.2009
comment
Большинство из этих языков не старше C ++, поэтому решение не может быть принято, если они будут делать что-то подобное. Но все в порядке, я уверен, что вы правы. Мне просто было любопытно, какой язык мог вдохновить C ++ на это решение. - person n1ckp; 28.10.2009
comment
@ N1ck: Хотя они могут быть старше библиотеки std. :) - person sbi; 28.10.2009
comment
Я часто использую map::count() для этой цели. - person anilbey; 27.08.2019

Стандарт говорит (23.3.1.2/1), что оператор [] возвращает (*((insert(make_pair(x, T()))).first)).second. Вот в чем причина. Возвращает ссылку T&. Невозможно вернуть недействительную ссылку. И он возвращает ссылку, потому что, я думаю, это очень удобно, не так ли?

person Kirill V. Lyadvinsky    schedule 28.10.2009
comment
Извините, возможно, мой вопрос был недостаточно ясным, но я спрашиваю причину стандарта. - person n1ckp; 28.10.2009
comment
Хорошо, удобно, что operator[] возвращает ссылку. Поэтому он должен что-то вставить, потому что нет возможности вернуть недопустимую ссылку. - person Kirill V. Lyadvinsky; 28.10.2009
comment
Посмотрите ответ Самуэля: stackoverflow.com/questions/1639544/1639573#1639573 - person sbi; 28.10.2009
comment
Почему они не делают константную версию, которая генерирует исключение? - person GManNickG; 28.10.2009
comment
Потому что исключение - для исключительных случаев. - person Kirill V. Lyadvinsky; 28.10.2009
comment
@GMan: Если operator[] карты не будет создавать значения, это будет функция поиска. И вы же не хотите, чтобы ваша функция поиска срабатывала, если она не находит то, что вы ищете, не так ли? - person sbi; 28.10.2009
comment
@sbi: разве вы еще не знаете, что он существует? Но да, я просто понял, что если бы это сработало так, как я хотел, это была бы находка, спасибо. - person n1ckp; 28.10.2009
comment
В значительной степени по никам подумал. Каждый раз, когда я когда-либо использовал карту для поиска, мне приходилось проверять, вернул ли find конец, а затем генерировать исключение, потому что это единственное подходящее действие. - person GManNickG; 28.10.2009
comment
@ n1ck: Если вы уже знаете, что он существует, то что не так с operator[] как таковым? - person sbi; 29.10.2009
comment
@GMan: посмотрите мои комментарии к этому вопросу: stackoverflow.com/questions/1462341 - person sbi; 29.10.2009
comment
потому что он утверждал бы в режиме отладки, если бы он этого не сделал, вместо того, чтобы просто создать (возможно, недействительный, поскольку второй элемент, возможно, построен по умолчанию), не сообщая мне, что означает, что я должен перехватить ошибку позже. - person n1ckp; 29.10.2009
comment
@ n1ck: В режиме отладки подойдет дополнительный assert(my_map.find(key)!=my_map.end());. - person sbi; 29.10.2009
comment
Я знаю, но это больше кода. Думаю, я всегда мог бы добавить класс-оболочку, обеспечивающий нужное мне поведение, если бы я действительно этого хотел. Что действительно заставило меня спросить, так это то, что я заменил вектор картой, рассчитывая на то, что компилятор найдет мне ошибки (не думал о карте []), и вместо того, чтобы утверждать правильность, когда я получил доступ к недопустимому индексу (мой ключ был int) он разбился позже, когда я попытался использовать (недействительный) элемент, который он создал. Это был не первый раз, когда у меня была проблема с таким поведением карты, поэтому я решил задать вопрос. Видя ответы, думаю, я единственный, кто это делает. ... - person n1ckp; 29.10.2009
comment
В любом случае, спасибо за обсуждение, благодаря которому я нашел кое-что, о чем я даже не подумал. Тем не менее, я придерживаюсь своей точки зрения, что такое поведение оператора [] не интуитивно понятно по сравнению с вектором. - person n1ckp; 29.10.2009

Чтобы ответить на ваш настоящий вопрос: нет убедительного объяснения того, почему это было сделано именно так. "Просто так".

Поскольку std::map является ассоциативным контейнером, нет четкого предопределенного диапазона ключей, который должен существовать (или не существовать) на карте (в отличие от совершенно другой ситуации с std::vector). Это означает, что с std::map вам понадобятся функции поиска как без вставки, так и без вставки. Можно перегрузить [] способом без вставки и предоставить функцию для вставки. Или можно было бы сделать наоборот: перегрузить [] как оператор вставки и предоставить функцию для поиска без вставки. Итак, кто-то когда-то решил последовать второму подходу. Вот и все.

Если бы они сделали наоборот, может быть, сегодня кто-нибудь задаст здесь обратную версию вашего вопроса.

person AnT    schedule 28.10.2009
comment
Думаю, это то, что я хотел знать, спасибо. Третий способ заключался бы в том, чтобы не предоставлять operator [] и обеспечивать поиск и вставку в двух функциях-членах (без перегрузки оператора). - person n1ckp; 28.10.2009
comment
@ n1ck: Обозначение [] довольно хорошо закрепилось в умах людей. Теоретически можно было не использовать его, но я не думаю, что это было очень вероятно. - person David Thornley; 28.10.2009
comment
Причина, приведенная выше Павлом Минаевым, довольно убедительна. - person ; 29.10.2009
comment
Который из? Что это давняя конвенция? Может быть, правда, но не убедительно. Что нет способа узнать, находится ли он в левой части задания? Это совсем неубедительно, поскольку может просто вызвать исключение или заявить о неопределенном поведении. Помните, первоначальный вопрос заключался в том, почему он отличается от std::vector. - person AnT; 29.10.2009
comment
См. Несколько убедительных объяснений, например, в комментариях под этим ответом. - person Sz.; 14.07.2019

Это для целей назначения:


void test()
{
   std::map<std::string, int >myMap;
   myMap["hello"] = 5;
}
person EToreo    schedule 28.10.2009
comment
Если бы это было основной причиной, то карта констант вернула бы ссылку на константу, которой нельзя присвоить значение, и operator[] для постоянных карт не пришлось бы создавать значение. Но нет даже operator[] для постоянных карт, вы, должно быть, ошибаетесь. - person sbi; 28.10.2009
comment
Я не уверен, почему я ошибаюсь ... похоже, что если на постоянной карте нет оператора ‹pre› [] ‹/pre›, это просто подтверждает мою точку зрения. - person EToreo; 28.10.2009
comment
Отсутствие operator[] для постоянных карт, кажется, указывает на то, что operator[] существует исключительно для изменения карт. Я почему-то неправильно понимаю то, о чем вы говорите. Если разработчики STL не думали, что operator[] какого-либо вида будет иметь смысл для постоянных карт, они, очевидно, видели весь смысл operator[] в изменении карты, как с назначением в ответе ... - person sth; 28.10.2009
comment
Наличие у operator[] двух совершенно разных семантик в зависимости от того, const карта или нет, звучит для меня как плохая идея. Таким образом, [] имеет определенную четко определенную семантику, которая просто не поддерживается для const map - следовательно, ее там нет. - person Pavel Minaev; 28.10.2009
comment
@EToreo & sth: Я вижу, что моя точка зрения была несколько слабой. <sheepish_grin> Позвольте мне ... Как бы то ни было, operator[] служит двум целям: вы можете использовать его для доступа к существующему элементу и вы можете вставлять элементы. Для обоих есть специализированные функции, так что, по-видимому, это комбинация, почему существует operator[]. Для семантики добавления у вас есть insert(), для семантики доступа у вас есть find() - за исключением того, что find() может возвращать несуществующий элемент, а оператор - нет. Семантика вставки необходима для добавления и поиска для работы с operator[]. - person sbi; 29.10.2009

Я думаю, это в основном потому, что в случае карты (в отличие от вектора, например) это довольно дешево и легко сделать - вам нужно создать только один элемент. В случае вектора они могут расширить вектор, чтобы сделать новый индекс действительным, но если ваш новый индекс намного превосходит то, что уже есть, добавление всех элементов до этого момента может быть довольно дорогостоящим. Когда вы расширяете вектор, вы также обычно указываете значения новых добавляемых элементов (хотя часто со значением по умолчанию). В этом случае не было бы возможности указать значения элементов в пространстве между существующими элементами и новым.

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

person Jerry Coffin    schedule 28.10.2009
comment
Что ж, я не уверен, что добавление нового элемента в вектор, когда индекс вне диапазона без вмешательства пользователя, будет именно тем поведением, которое я хочу. Если я обращаюсь к массиву, выходящему за рамки, это, вероятно, связано с ошибкой где-то в моем коде. Я не хочу, чтобы язык создал его для меня. Я даю вам +1 за вторую часть, хотя это не совсем мой личный опыт работы с картами. - person n1ckp; 28.10.2009

Он позволяет вставлять новые элементы с operator[], например:

std::map<std::string, int> m;
m["five"] = 5;

5 присваивается значению, возвращаемому m["five"], которое является ссылкой на вновь созданный элемент. Если operator[] не будет вставлять новые элементы, это не сработает.

person sth    schedule 28.10.2009
comment
см. мой комментарий на странице stackoverflow.com/questions/1639544/1639563#1639563, чтобы узнать, почему я считаю, что это неправильно. - person sbi; 28.10.2009

map.insert (ключ, элемент); проверяет наличие ключа на карте, но не перезаписывает существующее значение.

map.operator [ключ] = элемент; проверяет наличие ключа на карте и заменяет любое существующее значение элементом.

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

person me.    schedule 18.12.2009

Разница здесь в том, что карта хранит «индекс», то есть значение, хранящееся в карте (в ее базовом дереве RB), является std::pair, а не просто «индексированным» значением. Всегда есть map::find(), который сообщит вам, существует ли пара с данным ключом.

person Nikolai Fetissov    schedule 28.10.2009

Ответ в том, что им нужна была и удобная, и быстрая реализация.

Базовая реализация вектора - это массив. Итак, если в массиве 10 записей, а вам нужна запись 5, функция T & vector :: operator [] (5) просто возвращает headptr + 5. Если вы запросите ввод 5400, он вернет headptr + 5400.

Базовая реализация карты обычно представляет собой дерево. Каждый узел выделяется динамически, в отличие от вектора, который по стандарту должен быть непрерывным. Итак, nodeptr + 5 ничего не означает, а map ["некоторая строка"] не означает rootptr + offset ("некоторая строка").

Как и в случае поиска с картами, у вектора есть функция getAt (), если вы хотите проверить границы. В случае векторов проверка границ считалась ненужной платой для тех, кто этого не хотел. В случае с картами единственный способ не возвращать ссылку - это создать исключение, и это также считалось ненужными затратами для тех, кто этого не хотел.

person jmucchiello    schedule 28.10.2009
comment
Не могли бы они вернуть недопустимую ссылку, как если бы вы разыменовали std :: map 'end ()? - person n1ckp; 28.10.2009
comment
@ n1ck: Нет. В C ++ нет недопустимых ссылок. (Это одно из главных отличий от указателей.) - person sbi; 28.10.2009
comment
n1ck, подумай о логическом потоке. Чтобы вставить, программа должна найти, что поместить в дерево. Эта обработка имеет свою стоимость. Поскольку наиболее вероятным действием после того, как значение не найдено, является его вставка, почему бы просто не сделать вставку автоматически \ [\]. - person jmucchiello; 28.10.2009
comment
Что тогда, если вы разыменуете что-то вроде std :: map's end? или если разыменовать неверный указатель? То же поведение могло быть реализовано: если оно не существует: неопределенное поведение. - person n1ckp; 29.10.2009
comment
@jmucchiello: Хорошие комментарии. Я просто считаю использование operator [] неинтуитивным для этой цели, но да, вы вроде как правы. - person n1ckp; 29.10.2009
comment
@ n1ck: разница в том, что относительно легко и дешево проверить, равен ли итератор end() или находится ли индекс в правильном диапазоне. Дороже проверять наличие записи на карте. Но это не значит, что вы не можете сделать это до вызова operator[]. - person sbi; 29.10.2009
comment
Я полностью согласен. Я хочу сказать, почему оператор []. Я не говорю, что функции с таким поведением не должно существовать, но почему оператор []? Я думаю, это единственное, с чем мы не согласны. Хорошим ответом было то, что раньше это была конвенция, так почему бы не сохранить ее. Тогда мой вопрос: почему ОНИ выбрали его тогда? - person n1ckp; 29.10.2009

Рассмотрим такой ввод - 3 блока, в каждом блоке 2 строки, первая строка - количество элементов во втором:

5
13 20 22 43 146
4
13 22 43 146
5
13 43 67 89 146

Задача: подсчитать количество целых чисел, которые присутствуют во вторых строках всех трех блоков. (Для этого примера ввода вывод должен быть 3, поскольку 13, 43 и 146 присутствуют во вторых строках всех трех блоков)

Посмотрите, насколько хорош этот код:

int main ()
{
    int n, curr;
    map<unsigned, unsigned char> myMap;
    for (int i = 0; i < 3; ++i)
    {
        cin >> n;
        for (int j = 0; j < n; ++j)
        {
            cin >> curr;
            myMap[curr]++;
        }

    }

    unsigned count = 0;
    for (auto it = myMap.begin(); it != myMap.end(); ++it)
    {
        if (it->second == 3)
            ++count;
    }

    cout << count <<endl;
    return 0;
}

По стандарту operator[] возвращает ссылку на (*((insert(make_pair(key, T()))).first)).second. Вот почему я мог написать:

myMap[curr]++;

и он вставил элемент с ключом curr и инициализировал значение нулем, если ключ отсутствовал на карте. А также увеличивало значение вне зависимости от того, был ли элемент на карте или нет.

Видишь, как просто? Приятно, правда? Это хороший пример того, что это действительно удобно.

person Narek    schedule 07.05.2013
comment
Хммм, да, это может быть удобно и приятно, но зачем использовать operator [], а не более явную именованную функцию? Мне такое поведение не кажется интуитивным, и поэтому я нахожу странным поведение чего-то вроде operator [] вместо использования функции с явным именем для чего-то, что выполняет какую-то странную обработку, которая не является непосредственно интуитивно понятной. Я не говорю, что это неприятно, но почему у operator [] такое поведение, это могла быть стандартная функция. - person n1ckp; 17.05.2013
comment
Полагаю, у вас есть хороший опыт работы с другими языками программирования, не так ли? :) - person Narek; 18.05.2013
comment
да и нет, почему вы спрашиваете? Я в основном занимаюсь C ++, но знаю еще пару языков. - person n1ckp; 22.05.2013
comment
Я думал, что вы не C ++ парень, поэтому задаете этот вопрос. Но, кажется, есть еще одна причина :) - person Narek; 22.05.2013
comment
Причина, по которой я задал этот вопрос, заключается в том, что поведение не является интуитивным, и я хотел знать, ПОЧЕМУ оно было закодировано таким образом. Я, конечно, знал, КАК это действует, поэтому у меня не было проблем с этим. Спасибо за ответ, но это не то, что я искал. - person n1ckp; 23.05.2013
comment
Чтобы понять это, просто подумайте, а что, если бы все было не так, как есть. Было бы удобнее? - person Narek; 25.05.2013
comment
На мой взгляд, да, было бы более интуитивно понятно и удобно не создавать объект, поскольку operator [] является оператором индексации. Мне кажется странным создавать объект, если он не существует. Вот как это работает с вектором, так почему бы не с картой? - person n1ckp; 27.05.2013

Я знаю, что это старый вопрос, но, похоже, никто не ответил на него, ИМО. Пока я не видел упоминания об этом:

Следует избегать возможности неопределенного поведения! Если есть какое-либо разумное поведение, помимо UB, то, думаю, нам следует с этим согласиться.

std::vector/array демонстрирует неопределенное поведение с плохим operator[] индексом, потому что на самом деле нет разумного варианта, поскольку это одна из самых быстрых и фундаментальных вещей, которые вы можете сделать в c / c ++, и было бы неправильно пытаться что-либо проверить. Проверка - это то, для чего нужен at().

std::*associative_container* уже проделал работу по поиску того, куда будет помещен индексированный элемент, поэтому имеет смысл создать его там и вернуть. Это очень полезное поведение, и альтернативы operator[] выглядят гораздо менее аккуратно, но даже если создание и вставка нового элемента не то, что вы хотели или бесполезно для вас, это все равно гораздо лучший результат, чем неопределенное поведение.

Я думаю, что operator[] является наиболее предпочтительным синтаксисом для использования ассоциативного контейнера для удобства чтения, и для меня это очень интуитивно понятно и точно соответствует концепции operator[] для массивов: возвращает ссылку на элемент в этой позиции, чтобы использовать или назначить.

Если бы моя интуиция о том, что, если ничего нет, было бы только неопределенным поведением, тогда мне было бы абсолютно не хуже, так как я бы делал все, что мог, чтобы этого избежать, точка.

Потом однажды я узнал, что могу вставить элемент с _8 _... жизнь стала лучше.

person Orion    schedule 18.07.2021

Невозможно избежать создания объекта, потому что оператор [] не знает, как его использовать.

myMap["apple"] = "green";

or

char const * cColor = myMyp["apple"];

Я предлагаю в контейнер карты добавить такую ​​функцию, как

if( ! myMap.exist( "apple")) throw ...

читать намного проще и лучше, чем

if( myMap.find( "apple") != myMap.end()) throw ...

person Clemens    schedule 28.06.2013
comment
Не уверен, что вы имеете в виду, потому что оператор [] не знает, как его использовать. Если вы прочитаете мой ответ на другие ответы, как я уже сказал, моим первым ожиданием было бы действовать как вектор и сбой при недопустимом индексе. т.е. вектор ‹int› v; v [1] = 1; рухнет, почему бы не с картой? - person n1ckp; 13.07.2013
comment
@ n1ckp В случае вектора присвоение индекса за пределами текущего размера не допускается. Однако на карте можно назначить индекс, который в настоящее время не существует. - person BlueSilver; 28.02.2014
comment
@BlueSilver: это вообще мой вопрос, почему это разрешено для карты (но не для вектора)? Я знаю, как работает этот класс, я просто хочу знать, почему он был таким. Пожалуйста, прочтите другие комментарии и ответы, потому что я думаю, что это уже обсуждалось. - person n1ckp; 28.02.2014