This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-12-20
[Moved to DR at the October, 2012 meeting.]
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 twofs declare the same function template? Accordingto 13.7.7.2 [temp.over.link] paragraph 5,
Two expressions involving template parameters are consideredequivalent if two function definitions containing the expressionswould satisfy the one definition rule (6.3 [basic.def.odr]),except that the tokens used to name the template parameters may differas long as a token used to name a template parameter in one expressionis replaced by another token that names the same template parameter inthe other expression.
The relevant portion of 6.3 [basic.def.odr] paragraph 5 says,
in each definition ofD, corresponding names, looked upaccording to 6.5 [basic.lookup], shall refer to an entitydefined within the definition ofD, or shall refer to thesame entity, after overload resolution (12.2 [over.match]) andafter matching of partial template specialization (13.10.4 [temp.over]), except that a name can refer to a const object withinternal or no linkage if the object has the same literal type in alldefinitions ofD, and the object is initialized with aconstant expression (7.7 [expr.const]), and the value (butnot the address) of the object is used, and the object has the samevalue in all definitions ofD
This could be read either way, since overload resolution isn't doneat this point. Either we consider the result of the unqualified namelookup and say that the expressions aren't equivalent or we need anew rule for equivalence and merging of dependent calls.
Proposed resolution (December, 2011):
Change 13.7.7.2 [temp.over.link] paragraph 5 as follows:
Two expressions involving template parameters are consideredequivalent if two function definitions containing theexpressions would satisfy the one definition rule (6.3 [basic.def.odr]), except that the tokens used to name the templateparameters may differ as long as a token used to name a templateparameter in one expression is replaced by another token that namesthe same template parameter in the other expression.Fordetermining whether two dependent names (13.8.3 [temp.dep])are equivalent, only the name itself is considered, not the result ofname lookup in the context of the template. If multiple declarationsof the same function template differ in the result of this namelookup, the result for the first declaration is used.[Example:
template <int I, int J> void f(A<I+J>); // #1 template <int K, int L> void f(A<K+L>); // same as #1 template <class T> decltype(g(T())) h(); int g(int); template <class T> decltype(g(T())) h() // redeclaration ofh() uses the earlier lookup { return g(T()); } // ...although the lookup here does findg(int) int i = h<int>(); // template argument substitution fails;g(int) // was not in scope at the first declaration ofh()—end example] Two expressions...
Change 13.8.3 [temp.dep] paragraph 1 as follows:
...In an expression of the form:
postfix-expression(expression-listopt)
where thepostfix-expression is an
id-expressionunqualified-id, theid-expressionunqualified-iddenotes a dependent name if
any of the expressions in theexpression-list is a packexpansion (13.7.4 [temp.variadic]),
any of the expressions in theexpression-list is atype-dependent expression (13.8.3.3 [temp.dep.expr]), or
if theunqualified-id
of theid-expressionis atemplate-id in which any of the template arguments depends on atemplate parameter.if an operand...
Change 13.8.4.2 [temp.dep.candidate] paragraph 1 as follows:
For a function call
that depends on a template parameterwhere thepostfix-expression is a dependent name,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:
For the part of the lookup using unqualified name lookup(6.5.3 [basic.lookup.unqual])
or qualified name lookup (6.5.5 [basic.lookup.qual]), only function declarations from the templatedefinition context are found.For the part of the lookup using associated namespaces(6.5.4 [basic.lookup.argdep]), only function declarations found ineither the template definition context or the template instantiationcontext are found.
If
the function name is anunqualified-id andthecall would be ill-formed or would find a better match had the lookupwithin the associated namespaces considered all the functiondeclarations with external linkage introduced in those namespaces inall translation units, not just considering those declarations foundin the template definition and template instantiation contexts, thenthe program has undefined behavior.