Title
Instantiation of default arguments in lambda-expressions
Status
nad
Section
13.9.2 [temp.inst]
Submitter
Tom Honermann

Created on 2022-08-16.00:00:00 last changed 5 months ago

Messages

Date: 2023-11-16.21:27:26

CWG 2023-11-11

The behavior is as intended. Note that 13.9.2 [temp.inst] paragraph 3 applies to a class template specialization and its member functions. The examples do not involve class templates, but merely templated classes.

Date: 2022-08-16.00:00:00

Subclause 7.5.5.2 [expr.prim.lambda.closure] paragraph 2 specifies:

The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.

This means the closure type is a local class if the lambda-expression appears at function scope. A note in 13.9.2 [temp.inst] paragraph 2 claims that default arguments inside local classes are not separately instantiated:

[Note 3: Within a template declaration, a local class (11.6 [class.local]) or enumeration and the members of a local class are never considered to be entities that can be separately instantiated (this includes their default arguments, noexcept-specifier s, and non-static data member initializers, if any, but not their type-constraints or requires-clauses). As a result, the dependent names are looked up, the semantic constraints are checked, and any templates used are instantiated as part of the instantiation of the entity within which the local class or enumeration is declared. —end note]

However, 13.9.2 [temp.inst] paragraph 3 is not in harmony with the note:

The implicit instantiation of a class template specialization does not cause the implicit instantiation of default arguments or noexcept-specifier s of the class member functions.

Example:

  template<typename T>
  void ft() {
   [](T p = T::value) {}; // error even though the lambda is never called
  }
  template void ft<int>();

Even for a lambda declared at namespace scope is an unused default argument instantiated by major implementations:

  template<typename T>
  using ta = decltype([](T p = T::value) { // error
	     return p;
	    });
  auto g = ta<int>{}(0);
History
Date User Action Args
2023-11-16 21:27:26adminsetmessages: + msg7517
2023-11-16 21:27:26adminsetstatus: open -> nad
2022-08-16 00:00:00admincreate