2014-09-12 4 views
3
struct Foo 
{ 
    char name[10]; 
    int i; 
    double d; 
}; 

Я знаю, что я могу обнулить инициализировать все члены такого типа POD с:Zero-инициализация типов POD

Foo foo = {0}; 

Могу ли я еще больше упростить это:

Foo foo = {}; 

Как встроенные массивы? (int arr[10] = {};)


Я не спрашиваю, когда инициализируется с {0}, будут члены, кроме первого, равны нулю инициализирован. Я знаю, что ответ на этот вопрос - да. Я спрашиваю, можно ли синтаксически исключить первый 0.

Большинство учебников я нашел на эту тему предлагает использовать {0}, никто не используя {}, например, this guide, и это объясняется как Это работает, потому что агрегированные правила инициализации являются рекурсивными;, что дает больше путаницы, чем объяснение.

+0

@JoachimPileborg: Это ужасно вводит в заблуждение. 'int n;' is "как построение по умолчанию", но не устанавливается в ноль. Скорее всего, что '' {} 'похоже на инициализацию данных инициализацией данных. –

ответ

4

Как написано, это агрегатная инициализация. Применимо правило (§8.5.1 [dcl.init.aggr]/P7):

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

Соответствующие части §8.5.4 [dcl.init.list]/р3:

Список инициализация объекта или ссылки типа T определяется следующим образом:

  • Если T является агрегатом, выполняется агрегатная инициализация (8.5.1).
  • В противном случае, если в списке инициализаторов нет элементов, а T - тип класса с конструктором по умолчанию, объект инициализируется значением.
  • [нерелевантные элементы опущены]
  • В противном случае, если в списке инициализаторов нет элементов, объект инициализируется значением.

Короче говоря, Субагрегированные рекурсивно агрегированных инициализируется из пустого списка инициализации. Все остальное инициализируется значением. Таким образом, конечным результатом является все инициализируемое значением, при этом все, что является POD, инициализация значения означает нулевую инициализацию.


Если T является POD, но не агрегат, то агрегат инициализация не применяется, так что вы попали вторую точку пули в §8.5.4 [dcl.init.list]/р3, что приводит к значению вместо этого - инициализация всего объекта. Классы POD должны иметь тривиальный конструктор по умолчанию, который не предоставляется пользователю, поэтому инициализация значения для них также означает нулевую инициализацию.

Смежные вопросы