data_t d3 = {0}
- это список инициализации синтаксис, который с такими агрегатами, как data_t
, выполняет агрегатная инициализация : предоставленное значение 0
используется для инициализации первого элемента, а остальные элементы инициализируются с использованием соответствующих им значений по умолчанию, и, если таковых не существует, инициализируется значением ( выделение шахты , отредактировано для C ++ 14 ):
Если количество предложений инициализатора равно меньше , то число членов или список инициализатора равно полностью пустой, остальные члены инициализируются их инициализаторами элементов по умолчанию , если это предусмотрено в определении класса и в противном случае с помощью пустых списков, в соответствии с обычными правилами для инициализации списка (которые выполняют значение-инициализацию для не-класса типы и неагрегированные классы с конструкторами по умолчанию, и agg Регуляция инициализации для агрегатов). Если элемент ссылочного типа является одним из этих оставшихся элементов, программа является некорректной.
значение-инициализация означает нулевую инициализацию для неклассные типы. Именно из-за член num3
, который не имеет значения по умолчанию, получает значение 0
.
Примечание: это не следует путать с по умолчанию -инициализация , которая вообще не инициализирует неклассные типы. data_t d3;
будет default-initialization , и элемент num3
будет оставлен в неопределенном состоянии.
Важным моментом, за которым нужно следить, является ли объект или нет. инициализируется агрегат , потому что правила инициализации отличаются для агрегатов и классов с конструктором. В случае конструктора не принадлежащие классу члены без значения по умолчанию будут инициализированы по умолчанию (т.е. оставлены в неопределенном состоянии).
Некоторые примеры:
struct A { // an aggregate
int num1 = 100;
int num2 = -100;
int num3;
};
struct B { // not an aggregate
int num1 = 100;
int num2 = -100;
int num3;
B() {}
B(int) {}
};
int main() {
A a1; // default-initialization: a1 is {100, -100, ???}
A a2 = {}; // aggregate initialization: a2 is {100, -100, 0}
A a3 = { 1 }; // aggregate initialization: a3 is {1, -100, 0}
A a4 = { 1,2,3 }; // aggregate initialization: a4 is {1, 2, 3}
B b1; // default-initialization: b1 is {100, -100, ???}
B b2 = {}; // copy-list-initialization invoking B::B(): b2 is {100, -100, ???}
B b3 = { 1 }; // copy-list-initialization invoking B::B(int): b3 is {100, -100, ???}
B b4 = { 1,2,3 }; // error: no B constructor taking (int,int,int)
}
Обратите внимание также на то, что агрегат правила инициализации до C ++ 11. См., Например, этот связанный вопрос до C ++ 11: Что означает {0} при инициализации объекта?