Title
Qualified name lookup in a constrained context
Status
concepts
Section
6.5.5 [basic.lookup.qual]
Submitter
Daniel Krügler

Created on 2008-09-24.00:00:00 last changed 179 months ago

Messages

Date: 2010-03-29.00:00:00

According to 6.5.5 [basic.lookup.qual] paragraph 7,

In a constrained context (_N2914_.14.11 [temp.constrained]), a name prefixed by a nested-name-specifier that nominates a template type parameter T is looked up as follows: for each template requirement C<args> whose template argument list references T, the name is looked up as if the nested-name-specifier referenced C<args> instead of T (_N2960_.3.4.3.3 [concept.qual]), except that only the names of associated types are visible during this lookup. If an associated type of at least one requirement is found, then each name found shall refer to the same type. Otherwise, if the reference to the name occurs within a constrained context, the name is looked up within the scope of the archetype associated with T (and no special restriction on name visibility is in effect for this lookup).

In an example like,

    concept A<typename T> {
      typename assoc_type;
    }

    concept B<typename T> {
      typename assoc_type;
    }

    template<typename T>
    requires A<T>
    B<T::assoc_type>::assoc_type f();

it is not clear whether the argument T::assoc_type of B “references” T or not.

James Widman: In our mental model (and in our intentions while drafting), we still have a (non-archetype) dependent type for the T in your example, and, even after the SameType requirement is seen, we also have a distinct dependent type to represent A<T>::assoc_type (which itself is distinct from the type of the entity named assoc_type that lives in the scope of the concept A). And those two dependent types (A<T>::assoc_type and T) will both alias the same type archetype when that archetype is established (see the paragraph on establishment in _N2914_.14.11.2 [temp.archetype]).

I think 6.5.5 [basic.lookup.qual] paragraph 6 will read more easily if we change the “references a template parameter” verbiage to a generalized “dependent type” verbiage. (We shied away from that in the past because we wanted to say that there's nothing “dependent” within a constrained context. That's because we wanted to say that all name references are bound to something, overload resolution is done, etc. So certainly there are no instances of deferred name lookup or deferred overload resolution within a constrained context. But we still need to be able to say when a type, template, value or concept instance depends on a template parameter.) I propose we change this wording to read,

In a constrained context (_N2914_.14.11 [temp.constrained]), the identifier of an unqualified-id prefixed by a nested-name-specifier that nominates a dependent type T is looked up as follows: for each template requirement C<args> such that either T or an equivalent type (_N2914_.14.11.1 [temp.req]) is a template argument to C, the identifier of the unqualified-id is looked up as if the nested-name-specifier nominated C<args> instead of T (_N2960_.3.4.3.3 [concept.qual]), except that only the names of associated types and class templates (_N2914_.14.10.1.2 [concept.assoc]) are visible during this lookup. If an associated type or class template of at least one requirement is found, then the unqualified-id shall refer either to the same type or to an equivalent type when its identifier is looked up in each of the concepts of the other requirements where T is a template argument. [Note: no part of the procedure described in the preceding part of this paragraph results in the establishment of an archetype (_N2914_.14.11.2 [temp.archetype]). However, in the event that the unqualified-id is a template-id, one of its template arguments could contain some construct that would force archetype establishment. —end note] Otherwise, the name is looked up within the scope of the archetype aliased by T (and no special restriction on name visibility is in effect for this lookup). [Note: this establishes the archetype of T (if it was not established already). —end note]

(It looks like we have a wording nit to fix in the archetype establishment paragraph: it talks about a type archetype coming into existence “when it is used [in some way].” It seems odd to say that something is used in a particular way before it exists. We should instead say something like “when a necessarily-dependent type that would alias the archetype is used [in some way].”)

(It might also be nice to have a cleanup in the paragraph that introduces the notion of std::SameType and “equivalent types” (_N2914_.14.11.1 [temp.req] paragraph 3) so that the congruence relation is part of the normative text rather than a note.)

History
Date User Action Args
2009-08-03 00:00:00adminsetstatus: open -> concepts
2008-09-24 00:00:00admincreate