Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16112

Value initialization without default constructor

I was wondering under which circumstances a class may have no default constructor but will still be value-initialized. The typical case for "no default ctor" is that a parametrized one is present and the default ctor is not defaulted (= default).

Quoting from the 2020 standard, chapter 9.4.1, Initializers/General (the latest draft contains equivalent wording):

To value-initialize an object of type T means:
(8.1) — if T is a (possibly cv-qualified) class type (Clause 11), then
(8.1.1) — if T has either no default constructor (11.4.5.2) or a default constructor that is user-provided or deleted, then the object is default-initialized;

And

11.4.5.2 Default constructors [class.default.ctor]: 1 A default constructor for a class X is a constructor of class X for which each parameter that is not a function parameter pack has a default argument (including the case of a constructor with no parameters). If there is no user-declared constructor for class X, a non-explicit constructor having no parameters is implicitly declared as defaulted (9.5)

I read this such that 8.1.1 does not refer to cases with no constructor at all (because, as 11.4.5.2 explains, a default constructor is then implicitly declared). Instead I understand it as "No default constructor at all" (including implicit ones).

Value-initialization happens with new()or brace-initialization, and for excess elements in arrays that are brace-initialized (as in struct T{}; T arr[1]{};).

Neither construct compiles when there is "no default constructor". Are there situations where objects of types without default constructor are value-initialized at all? Am I misreading 8.1.1?

Upvotes: 5

Views: 1088

Answers (1)

Davis Herring
Davis Herring

Reputation: 40033

It’s just saying that value-initializing an object of a class type that lacks a default constructor tries and fails to default-initialize it. Note that the alternative in the next bullet still default-initializes it after zero-initializing it, so it’s not default-initialized any more for not having a default constructor.

Depending on one’s interpretation of [class.default.ctor], it might also be considered to cover the case where a class can be default-initialized via a variadic constructor template:

struct A {
  template<class ...TT> A(TT...);
};
auto a=A();  // value-initialization -> default-initialization

Upvotes: 2

Related Questions