std :: map значение по умолчанию для встроенного типа - PullRequest
27 голосов
/ 24 декабря 2010

Недавно меня смутила функция std :: map operator [].В библиотеке MSDN написано: «Если значение ключа аргумента не найдено, оно вставляется вместе со значением по умолчанию для типа данных».Я попытался найти гораздо более точное объяснение этой проблемы.Например, здесь: std :: map значение по умолчанию На этой странице Майкл Андерсон сказал, что «значение по умолчанию создается конструктором по умолчанию (конструктором нулевого параметра)».

Теперь мой квестдоходит до этого: «какое значение по умолчанию для встроенного типа?».Это было связано с компилятором?Или существует стандарт для этой проблемы комитетом c ++ stardard?

Я провел тест на Visual Studio 2008 для типа "int" и обнаружил, что тип "int" создается со значением 0.

Ответы [ 4 ]

26 голосов
/ 24 декабря 2010

Это определено в стандарте, да. карта выполняет "инициализацию по умолчанию" в этом случае. Как вы говорите, для типов классов это вызывает конструктор без аргументов.

Для встроенных типов в стандарте 98 см. Раздел 8.5 «Инициализаторы»:

По умолчанию инициализировать объект типа T означает:

  • если T не POD ...
  • если T является типом массива ...
  • в противном случае хранилище для объекта инициализируется нулями

А ранее

Инициализация нуля хранилища для объекта типа T означает:

  • если T является скалярным типом, для хранилища устанавливается значение 0 (ноль), преобразованное в T

Скалярные типы:

  • Арифметические типы (целые, с плавающей точкой)
  • Типы перечисления
  • Типы указателей
  • Указатель на типы элементов

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

18 голосов
/ 19 октября 2012

Стандарт C ++ 11 по-прежнему требует, чтобы std :: map обнулял встроенные типы (как и предыдущий стандарт), но причины немного отличаются от тех, что приведены в ответе Люка Холливелла. В частности, «инициализация по умолчанию» для встроенного типа данных не означает , что означает «инициализация нуля» в стандарте C ++ 11, а скорее означает «ничего не делать». То, что на самом деле происходит в std::map::operator[], является «инициализацией значения».

Тем не менее, конечный результат в новом стандарте такой же, как в ответе Люка. Значения будут инициализированы нулями. Вот соответствующие части стандарта:

Раздел 23.4.4.3 «Доступ к элементу карты» говорит

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

Эффекты: если на карте нет ключа, эквивалентного x, вставляется value_type(x, T()) в карту.

...

Выражение T() описано в разделе 8.5

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

X a();

И этот тип 'инициализации значения' описан в том же разделе

Инициализация значения объекта типа T означает:

  • если T является (возможно, cv-квалифицированным) типом класса (раздел 9) с предоставленным пользователем конструктором (12.1), тогда конструктор по умолчанию для T называется (и инициализация плохо сформирована, если T не имеет доступных конструктор по умолчанию);
  • если T является (возможно, cv-квалифицированным) типом класса без объединения без конструктора, предоставленного пользователем, то объект инициализируется нулями и, если Неявно объявленный конструктор T по умолчанию является нетривиальным, что конструктор называется.
  • если T является типом массива, то каждый элемент инициализируется значением;
  • в противном случае объект инициализируется нулями.
8 голосов
/ 24 декабря 2010

Значением по умолчанию для объектов типа класса является значение, установленное конструктором по умолчанию для класса. Для встроенных типов значение по умолчанию равно 0.

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

int i;          // i has an arbitrary undefined value
int x = int();  // x is 0
4 голосов
/ 24 декабря 2010
 |expression:   | POD type T                               | non-POD type T
 ==================================================================================================
 | new T         | not initialized                          | default-initialized
 | new T()       | always default-initialized               | always default-initialized
 | new T(x)      | always initialized via a constructor     | always initialized via a constructor

Насколько я знаю, stl использует новый T () для значений по умолчанию, поэтому он будет инициализирован по умолчанию, если int равен 0.

...