6

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?

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

5 Comments

The next bullet point starts with "otherwise", so it cannot refer to the same case. Regarding the "tries and fails": I'm missing the "fails", that's why I'm asking. But some obscure template issue may be a reason for the wording. (Although -- with the caveat of being ignorant about variadic templates -- I'd assume that the "no arguments" case would qualify as "default constructor".)
I think this means that the rules for "value initialization" doesn't forbid its use with non-default-constructible types, rather it delegates to the rules for "default initialization", which would in turn forbid it. I'm not sure why they would write it out like this, and I couldn't find what "default initialization" does with a type that doesn't have a default constructor (those rules seem to already assume there is a default constructor).
@Peter-ReinstateMonica: Of course the next bullet cannot apply; my point is that making it apply (by, say, removing "either no default constructor (11.4.5.2) or") wouldn't change whether such value initialization performs (or tries to perform) default initialization.
@FrançoisAndrieux: Right—and default initialization in turn fails in overload resolution. Lots of the standard is written in terms of “subroutine calls” like this, since it provides consistency; this one prevents performing zero-initialization and “then” being ill-formed, which might be even more confusing. (Really, it’s the “semantic constraints for default-initialization are checked” that’s weird here; there has been talk of simplifying that part.)
@DavisHerring I suppose the "let the default initialization clause spell out that it will fail" interpretation is right; but I'd had much preferred if they had said in the value-initialization definition "If T has no default constructor or a default constructor that is deleted, then the program is ill-formed", and in an additional paragraph covered the user-provided default ctor, referring initialization to default-initialization.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.