Подтвердить что ты не робот

Map operator [] и bool как значение

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

Имеем: std::map<std::string, bool> map_xxx;

Гарантировано ли, что после доступа к несуществующему ключу map_xxx["nonexistent_key"] значение второго аргумента всегда будет false?

пс. если нет, какие-либо идеи, как иметь такое поведение?

4b9b3361

Ответ 1

Да. Вводимое значение должно быть false.


В С++ 98 механизм был вызван инициализацией по умолчанию, указанной как нулевая инициализация для неклассов; что false для булевых.

Так как С++ 03, механизм называется инициализацией значения, все еще заданной как нулевая инициализация для неклассов; и тем самым false для булевых. Например, посмотрим, что говорит С++ 14.

Из § 23.4.4.3; просто замените bool на "T".

T & operator [] (const key_type & x);

  • Эффекты: Если на карте нет ключа, эквивалентного x, вставляет в карту значение_имя (x, T()).
  • Требуется: key_type должен быть CopyInsertable и mapped_type должен быть DefaultInsertable в * Это.

Из § 8.5 переведите абзацы снизу вверх:

Для нулевой инициализации объекта или ссылки типа T означает:

- если T - скалярный тип (3.9), объект инициализируется значением, полученным преобразованием целочисленного литерала 0 (ноль) в T;

...

В value-initialize объект типа T означает:

- если T является классом класса (возможно, cv-qualit) (раздел 9) без конструктора по умолчанию (12.1) или конструктора по умолчанию, который предоставляется или удаляется пользователем, тогда объект инициализируется по умолчанию;

- если T является классом класса (возможно, cv-qualit) без предоставленного пользователем или удаленного конструктора по умолчанию, тогда объект инициализируется нулем и семантические ограничения для инициализации по умолчанию проверяются, а если T имеет не- -ривиальный конструктор по умолчанию, объект инициализируется по умолчанию;

- если T - тип массива, то каждый элемент инициализируется значением;

- в противном случае объект с нулевой инициализацией.

...

Объект, инициализатор которого представляет собой пустой набор скобок, т.е. (), должен быть инициализирован значением.

Из § 4.12:

Значение арифметики, неперечисленное перечисление, указатель или указатель на тип члена может быть преобразовано в prvalue типа bool. Значение нулевое значение, значение нулевого указателя или значение указателя нулевого элемента преобразуется в значение false; любое другое значение преобразуется в значение true. Для прямой инициализации (8.5) prvalue типа std:: nullptr_t может быть преобразовано в prvalue типа bool; результирующее значение false.