Title
Template parameters in member selections
Status
open
Section
6.5.5.1 [basic.lookup.qual.general]
Submitter
Daveed Vandevoorde

Created on 2010-06-29.00:00:00 last changed 11 months ago

Messages

Date: 2023-12-02.13:35:39

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.

Date: 2020-11-15.00:00:00

Additional note (November, 2020):

Paper P1787R6, adopted at the November, 2020 meeting, partially addresses this issue.

Date: 2010-06-29.00:00:00

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.

History
Date User Action Args
2023-12-02 13:35:39adminsetmessages: + msg7529
2023-12-02 13:35:39adminsetstatus: drafting -> open
2020-12-15 00:00:00adminsetmessages: + msg6230
2010-06-29 00:00:00admincreate