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
In an example like
template<typename T> void f(T p)->decltype(p.T::x);
The nested-name-specifier T:: looks like it refers to the template parameter. However, if this is instantiated with a type like
struct T { int x; }; struct S: T { };
the reference will be ambiguous, since it is looked up in both the context of the expression, finding the template parameter, and in the class, finding the base class injected-class-name, and this could be a deduction failure. As a result, the same declaration with a different parameter name
template<typename U> void f(U p)->decltype(p.U::x);
is, in fact, not a redeclaration because the two can be distinguished by SFINAE.
It would be better to add a new lookup rule that says that if a name in a template definition resolves to a template parameter, that name is not subject to further lookup at instantiation time.
Additional note (November, 2020):
Paper P1787R6, adopted at the November, 2020 meeting, partially addresses this issue.
CWG 2023-12-01
Per the status quo rules, T::x is a dependent name and thus no lookup occurs at template definition time. At template instantiation time, T is first looked up in the class of p and, if not found, the template parameter T is found. This, in turn, implies that the two templates discussed above are not equivalent, because the first potentially references a T member, the other a U member of p.
Subclause 13.7.7.2 [temp.over.link] paragraph 5 is not in conflict with this interpretation, because no lookup occurs for the T token inside the decltype at template definition time at all, thus (reliably) "name a template parameter" is not satisfied at that point.
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. ...
In order to clarify this, suggestions for a note including the example from this issue are welcome.