9
votes

enter image description hereThese two lines from cppreference

What is the difference between these two statements ? I don't see any difference

until c++14

If the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed. Otherwise, if T is an aggregate type, aggregate initialization is performed.

since c++14

If T is an aggregate type, aggregate initialization is performed. Otherwise, if the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed.

2
Thank You @cigien and @StoryTeller for edits.pvc

2 Answers

3
votes

The difference is which one happens when both conditions apply: if T is an aggregate class (as opposed to an array), which certainly has a default constructor, and the braced-init-list is empty. Of course, to understand why that matters, we then have to distinguish value initialization from aggregate initialization from an empty list.

Value initialization zero-initializes the object and then default-initializes it, which for an aggregate is default-initializing each of its members, so the value-initialization is member-wise (plus zeroing padding). Aggregate initialization initializes each member from {}, which is again value initialization for many types but is default initialization for members of class type with a user-provided default constructor. The difference can be seen in

struct A {A() {} int i;};
struct B {A a;};  // aggregate
B b{};     // i is 0 in C++11, uninitialized in C++14
B b2=B();  // i is 0 in both versions

In C++14 only, aggregates can have default member initializers; that can't contribute to a difference in behavior between the two language versions, of course, but it doesn't behave differently between these two rules anyway (since it replaces only the common default initialization).

0
votes

The difference is the sequence of checking, so the aggregate type checking is taking place at the first place, and only then the rest.