[temp.res.general] (original) (raw)

13 Templates [temp]

13.8 Name resolution [temp.res]

13.8.1 General [temp.res.general]

A name that appears in a declaration D of a template T is looked up from where it appears in an unspecified declaration of Tthat either is D itself or is reachable from D and from which no other declaration of Tthat contains the usage of the name is reachable.

If the name is dependent (as specified in [temp.dep]), it is looked up for each specialization (after substitution) because the lookup depends on a template parameter.

[Note 1:

Some dependent names are also looked up during parsing to determine that they are dependent or to interpret following < tokens.

A using-declarator is never dependent in a specialization and is therefore replaced during lookup for that specialization ([basic.lookup]).

— _end note_]

[Example 1: struct A { operator int(); };template<class B, class T> struct D : B { T get() { return operator T(); } };int f(D<A, int> d) { return d.get(); } — _end example_]

[Example 2: void f(char);template<class T> void g(T t) { f(1); f(T(1)); f(t); dd++; } enum E { e };void f(E);double dd;void h() { g(e); g('a'); } — _end example_]

[Example 3: struct A { struct B { };int a;int Y;};int a;template<class T> struct Y : T { struct B { }; B b; void f(int i) { a = i; } Y* p; }; Y<A> ya;

The members A​::​B, A​::​a, and A​::​Yof the template argument Ado not affect the binding of names in Y<A>.

— _end example_]

If the validity or meaning of the program would be changed by considering a default argument or default template argument introduced in a declaration that is reachable from the point of instantiation of a specialization ([temp.point]) but is not found by lookup for the specialization, the program is ill-formed, no diagnostic required.

[Note 2:

The usual qualified name lookup ([basic.lookup.qual]) applies even in the presence of typename.

— _end note_]

[Example 4: struct A { struct X { };int X;};struct B { struct X { };};template<class T> void f(T t) { typename T::X x;} void foo() { A a; B b; f(b); f(a); } — _end example_]

A qualified or unqualified name is said to be in a type-only contextif it is the terminal name of

[Example 5: template<class T> T::R f(); template<class T> void f(T::R); template<class T> struct S { using Ptr = PtrTraits<T>::Ptr; T::R f(T::P p) { return static_cast<T::R>(p); } auto g() -> S<T*>::Ptr; };template<typename T> void f() { void (*pf)(T::X); void g(T::X); } — _end example_]

A qualified-idwhose terminal name is dependent and that is in a type-only context is considered to denote a type.

[Example 6: template <class T> void f(int i) { T::x * i; } struct Foo { typedef int x;};struct Bar { static int const x = 5;};int main() { f<Bar>(1); f<Foo>(1); } — _end example_]

The validity of a templated entity may be checked prior to any instantiation.

[Note 3:

Knowing which names are type names allows the syntax of every template to be checked in this way.

— _end note_]

The program is ill-formed, no diagnostic required, if

[Note 4:

This can happen in situations including the following:

— _end note_]

[Note 5:

If a template is instantiated, errors will be diagnosed according to the other rules in this document.

Exactly when these errors are diagnosed is a quality of implementation issue.

— _end note_]

[Example 7: int j;template<class T> class X { void f(T t, int i, char* p) { t = i; p = i; p = j; X<T>::g(t); X<T>::h(); } void g(T t) { +; } };template<class... T> struct A { void operator++(int, T... t); };template<class... T> union X : T... { }; template<class... T> struct A : T..., T... { }; — _end example_]