List initialization - What changed in C++14?
Asked Answered
C

2

9

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.

Crosswise answered 28/6, 2020 at 14:13 Comment(1)
Thank You @cigien and @StoryTeller for edits.Crosswise
K
3

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

Kiker answered 28/6, 2020 at 14:54 Comment(3)
Not all aggregates have a non-deleted default constructor (e.g., struct X {const int x; };).Grimm
@T.C.: That’s true, but whether the constructor is deleted isn’t considered here (except that of course the initialization may be ill-formed). Or is that your point, that initializing such a type with {} is ill-formed in C++11 but not in C++14?Kiker
In N3337, the well-formedness depends on whether X's deleted default constructor is trivial - which I think it is under the definition at the time. If I'm reading the wiki notes correctly, CWG1301 changed the definition of value-initialization to reject deleted constructors, and reordered the bullet to preserve the validity of {}.Grimm
S
0

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

Squarely answered 28/6, 2020 at 14:42 Comment(1)
And what effect does this change have?Cockerham

© 2022 - 2024 — McMap. All rights reserved.