Date
2022-09-25.18:08:42
Message id
3505

Content

Consider the following example:

  int g(int);

  template <class T> decltype(g(T())) f();

  int g();

  template <class T> decltype(g(T())) f() { return g(T()); }

  int i = f<int>();

Do the two fs declare the same function template? According to 13.7.7.2 [temp.over.link] paragraph 5,

Two expressions involving template parameters are considered equivalent if two function definitions containing the expressions would satisfy the one definition rule (6.3 [basic.def.odr]), except that the tokens used to name the template parameters may differ as long as a token used to name a template parameter in one expression is replaced by another token that names the same template parameter in the other expression.

The relevant portion of 6.3 [basic.def.odr] paragraph 5 says,

in each definition of D, corresponding names, looked up according to 6.5 [basic.lookup], shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (12.2 [over.match]) and after matching of partial template specialization (13.10.4 [temp.over]), except that a name can refer to a const object with internal or no linkage if the object has the same literal type in all definitions of D, and the object is initialized with a constant expression (7.7 [expr.const]), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D

This could be read either way, since overload resolution isn't done at this point. Either we consider the result of the unqualified name lookup and say that the expressions aren't equivalent or we need a new rule for equivalence and merging of dependent calls.