C++ non-static data member initializers, just a little bit confused

T object = {arg1, arg2, ...}; is syntax for list initialization. There is no copying involved.

T object = T() is not list initialization. The right hand operand constructs a value-initialized temporary, and object is move- or copy-initialized from it. The move and copy can be elided, but the type must be movable or copyable, otherwise this is not allowed.


That's because, conceptually, that line constructs from Base(), which requires a copy/move constructor. The probable reason why you weren't aware of this, is because that expression generally triggers copy elision: a standard optimization. It's one of those C++ gotcha's.

(31.3) — when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move.

As for why Base b2 = {} works, see

(3.4) — Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.

You could just do Base b;.

Tags:

C++

C++11