Title
Instantiation of unused default member initializer
Status
drafting
Section
13.9.2 [temp.inst]
Submitter
Anoop S. Rana

Created on 2025-12-12.00:00:00 last changed 4 days ago

Messages

Date: 2026-04-17.22:17:22

CWG 2026-04-17

CWG agreed with the intent to make the Wrapper2 case well-formed. The end result should be consistent with unused default member initializers (not) causing odr-use.

Date: 2026-04-17.18:17:34

Possible resolution:

Change in 13.9.2 [temp.inst] paragraph 11 as follows:

An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class or static data member of a templated class, or a substatement of a constexpr if statement (8.5.2 [stmt.if]), unless such instantiation is required.

[Note 4: The instantiation of a generic lambda does not require instantiation of substatements of a constexpr if statement within its compound-statement unless the call operator template is instantiated. —end note]

It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated. The use of a template specialization in a default argument or default member initializer shall not cause the template to be implicitly instantiated except where needed to determine the correctness of the default argument or default member initializer. The use of a default argument in a function call causes specializations in the default argument to be implicitly instantiated. Similarly, the use of a default member initializer in a constructor definition or an aggregate initialization causes specializations in the default member initializer to be instantiated.

Let I be a default argument or default member initializer for a parameter or member, respectively, of type T, considering I to include the initialization of the parameter or member from the initializer-clause or brace-or-equal-initializer, respectively. Each templated entity X referenced by I is instantiated if needed to determine the correctness of I. Additionally, for the purposes of determining whether a definition of X is required to exist or whether the existence of a definition for X affects the semantics of the program, I is considered to be a templated function F having the form T F() { return I; }, and a function call, constructor definition or aggregate initialization that uses I is considered to call F. [Note: Whether X is instantiated can therefore depend on whether the definition of F is instantiated, which in turn can depend on whether a function call or aggregate initialization that uses I is potentially-evaluated. This rule applies even if I is not itself templated.]

Date: 2026-04-17.18:06:27

(From submission #830.)

Consider:

  struct Wrapper {
    Wrapper(int) {}
  };

  template <int N>
  struct Test {
    Test() : w(0) {}
    Wrapper w{};    //MSVC, GCC, EDG accept, but Clang rejects
  };

  Test<0> t;

Is the default member initializer instantiated together with the rest of the class template specialization, or only when actually needed?

Also consider:

  template <int N>
  struct Wrapper2 {
    Wrapper2(int) {}
  };

  template <int N>
  struct Test2 {
    Test2() : w(0) {}
    Wrapper2<N> w{};    //everybody accepts
  };

  Test2<0> t;
History
Date User Action Args
2026-04-17 22:17:22adminsetmessages: + msg8541
2026-04-17 22:17:22adminsetstatus: open -> drafting
2026-04-16 21:27:30adminsetmessages: + msg8534
2025-12-12 00:00:00admincreate