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

Std:: map значение по умолчанию для встроенного типа

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

Теперь мой квест приходит к следующему: "какое значение по умолчанию для типа сборки?". Был ли он связан с компилятором? Или есть стандарт для этой проблемы комитетом звезд С++?

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

4b9b3361

Ответ 1

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

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

Для инициализации объекта типа T по умолчанию:

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

И, ранее,

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

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

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

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

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

Ответ 2

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

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

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

Т & 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-квалифицированным) классом типа non-union без предоставленного пользователем конструктора, тогда объект инициализируется нулем и, если Ts неявно объявленный конструктор по умолчанию является нетривиальным, что конструктор.
  • если T - тип массива, то каждый элемент инициализируется значением;
  • , объект инициализируется нулем.

Ответ 3

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

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

int i;          // i has an arbitrary undefined value
int x = int();  // x is 0

Ответ 4

 |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.