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

2023-02-07


448. Set of template functions in call with dependent explicit argument

Section: 13.8.2  [temp.local]     Status: C++11     Submitter: Mark Mitchell     Date: 4 Jan 2004

[Voted into WP at August, 2010 meeting.]

Is this program valid?

  template <typename T> int g(int);
  class h{};
  template <typename T> int l(){h j; return g<T>(j);}
  template <typename T> int g(const h&);
  class j{};
  int jj(){return l<j>();}

The key issue is when "g" is looked up, i.e., whether both overloaded template "g" functions are available at the call site or only the first. Clearly, the entire postfix-expression "g<T>(j)" is dependent, but when is the set of available template functions determined?

For consistency with the rules about when the set of available overloads is determined when calling a function given by an unqualified-id, I would think that we should postpone determining the set of template functions if (and only if) any of the explicit template arguments are dependent.

John Spicer: I agree that there should be a core issue for this. The definition of "dependent name" (13.8.3 [temp.dep] paragraph 1) should probably be modified to cover this case. It currently only handles cases where the function name is a simple identifier.

Notes from the March 2004 meeting:

A related issue is a call with a qualified name and dependent arguments, e.g., x::y(depa, depb).

Proposed resolution (June, 2010):

  1. Change 13.8.3 [temp.dep] paragraph 1 as follows:

  2. ...In an expression of the form:

    where the postfix-expression is an unqualified-id id-expression, the unqualified-id id-expression denotes a dependent name if and only if any of the expressions in the expression-list is a type-dependent expression (13.8.3.3 [temp.dep.expr]) or if the unqualified-id of the id-expression is a template-id in which any of the template arguments depends on a template parameter. If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name. Such names are unbound and are looked up at the point of the template instantiation (13.8.4.1 [temp.point]) in both the context of the template definition and the context of the point of instantiation.

  3. Change 13.8.4.2 [temp.dep.candidate] paragraph 1 as follows:

  4. For a function call that depends on a template parameter, if the function name is an unqualified-id or if the function is called using operator notation, the candidate functions are found using the usual lookup rules (6.5.3 [basic.lookup.unqual], 6.5.4 [basic.lookup.argdep], 6.5.5 [basic.lookup.qual]) except that:

    If the function name is an unqualified-id and the call would be ill-formed or would find a better match had the lookup within the associated namespaces considered all the function declarations with external linkage introduced in those namespaces in all translation units, not just considering those declarations found in the template definition and template instantiation contexts, then the program has undefined behavior.