This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-11-11


2769. Substitution into template parameters and default template arguments should be interleaved

Section: 13.10.3.1  [temp.deduct.general]     Status: open     Submitter: Richard Smith     Date: 2023-07-14

Subclause 13.10.3.1 [temp.deduct.general] paragraph 5 specifies:

If a template argument has not been deduced and its corresponding template parameter has a default argument, the template argument is determined by substituting the template arguments determined for preceding template parameters into the default argument. ... When all template arguments have been deduced or obtained from default template arguments, all uses of template parameters in the template parameter list of the template are replaced with the corresponding deduced or default argument values.

This description is confused. We need to have already substituted into the template parameter declaration in order to finish forming a template argument, and we need to finish forming a template argument before we can substitute it into a later default template argument. Consider:

  struct X { constexpr operator int() { return 0; } };
  template<const int*> struct Y {};
  extern int arr[];
  template<typename T, T K = X(), const int *p = &arr[K], Y<p> y = {}> struct A {};
  A<int> a;

Here, we need to substitute T = int into the type of K, then convert the default template argument X() to int, then substitute the converted value of p into the type of y. The substitution into template parameters and into default template arguments is necessarily interleaved.

Suggested resolution:

Change in 13.10.3.1 [temp.deduct.general] paragraph 5 as follows:

The resulting substituted and adjusted function type is used as the type of the function template for template argument deduction. For each template parameter in turn: If the function template has associated constraints (13.5.3 [temp.constr.decl]), those constraints are checked for satisfaction (13.5.2 [temp.constr.constr]). ...