Title
Constrained auto and redeclaration with non-abbreviated syntax
Status
open
Section
9.3.4.6 [dcl.fct]
Submitter
Richard Smith

Created on 2023-09-26.00:00:00 last changed 15 months ago

Messages

Date: 2023-09-26.00:00:00

Consider:

  template<typename T> void f(T);
  void f(auto);

These are redeclarations according to 9.3.4.6 [dcl.fct] paragraph 22:

... An abbreviated function template is equivalent to a function template (13.7.7 [temp.fct]) whose template-parameter-list includes one invented type template-parameter for each generic parameter type placeholder of the function declaration, in order of appearance. ...

The same applies to constrained abbreviated functions:

  template<C T> void g(T);
  void g(C auto);          // redeclaration

However, this leads to a situation where two function templates are equivalent, but not functionally equivalent:

  template<typename T> requires D<T> void h(C auto); // #1
  template<typename T, C U> requires D<T> void h(U); // #2

According to 13.5.3 [temp.constr.decl] bullet 3.3, #1 has the associated constraints D<T> && C<auto_param_1> whereas #2 has the associated constraints C<U> && D<T> (note reverse order). Those are observably different because satisfaction is checked in lexical order and instantiation of one of the associated constraints may yield an error not in the immediate context.

A number of options are available:

  • Change 13.5.3 [temp.constr.decl] bullet 3.3 to check constraints from function parameters before those introduced by a requires-clause in the template-head.
  • Do not defined the non-abbreviated form to be "equivalent" to the abbreviated function template in 9.3.4.6 [dcl.fct] paragraph 22. Redeclarations thus cannot use the other syntax.
  • The "equivalent" only applies to non-constrained auto parameters.
  • The "equivalent to" rule could append to the requires-clause in the template-head instead of inventing a constrained template parameter.
History
Date User Action Args
2023-09-26 00:00:00admincreate