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 T that either is D itself or is reachable from D and from which no other declaration of T that 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.
Uses of other names might be type-dependent or value-dependent ([temp.dep.expr], [temp.dep.constexpr]).
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(); } // conversion-function-id is dependent }; int f(D<A, int> d) { return d.get(); } // OK, lookup finds A​::​operator int — end example]
[Example 2: void f(char); template<class T> void g(T t) { f(1); // f(char) f(T(1)); // dependent f(t); // dependent dd++; // not dependent; error: declaration for dd not found } enum E { e }; void f(E); double dd; void h() { g(e); // will cause one call of f(char) followed by two calls of f(E) g('a'); // will cause three calls of f(char) } — end example]
[Example 3: struct A { struct B { /* ... */ }; int a; int Y; }; int a; template<class T> struct Y : T { struct B { /* ... */ }; B b; // The B defined in Y void f(int i) { a = i; } // ​::​a Y* p; // Y<T> }; Y<A> ya;
The members A​::​B, A​::​a, and A​::​Y of the template argument A do 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.
The component names of a typename-specifier are its identifier (if any) and those of its nested-name-specifier and simple-template-id (if any).
A typename-specifier denotes the type or class template denoted by the simple-type-specifier ([dcl.type.simple]) formed by omitting the keyword typename.
[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); // OK, T​::​X refers to B​::​X f(a); // error: T​::​X refers to the data member A​::​X not the struct A​::​X } — end example]
A qualified or unqualified name is said to be in a type-only context if it is the terminal name of
[Example 5: template<class T> T::R f(); // OK, return type of a function declaration at global scope template<class T> void f(T::R); // ill-formed, no diagnostic required: attempt to declare // a void variable template template<class T> struct S { using Ptr = PtrTraits<T>::Ptr; // OK, in a defining-type-id T::R f(T::P p) { // OK, class scope return static_cast<T::R>(p); // OK, type-id of a static_cast } auto g() -> S<T*>::Ptr; // OK, trailing-return-type }; template<typename T> void f() { void (*pf)(T::X); // variable pf of type void* initialized with T​::​X void g(T::X); // error: T​::​X at block scope does not denote a type // (attempt to declare a void variable) } — end example]
A qualified-id whose terminal name is dependent and that is in a type-only context is considered to denote a type.
A name that refers to a using-declarator whose terminal name is dependent is interpreted as a typedef-name if the using-declarator uses the keyword typename.
[Example 6: template <class T> void f(int i) { T::x * i; // expression, not the declaration of a variable i } struct Foo { typedef int x; }; struct Bar { static int const x = 5; }; int main() { f<Bar>(1); // OK f<Foo>(1); // error: Foo​::​x is a type } — 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:
  • no valid specialization, ignoring static_assert-declarations that fail ([dcl.pre]), can be generated for a templated entity or a substatement of a constexpr if statement ([stmt.if]) within a templated entity and the innermost enclosing template is not instantiated, or
  • no specialization of an alias template ([temp.alias]) is valid and no specialization of the alias template is named in the program, or
  • any constraint-expression in the program, introduced or otherwise, has (in its normal form) an atomic constraint A where no satisfaction check of A could be well-formed and no satisfaction check of A is performed, or
  • every valid specialization of a variadic template requires an empty template parameter pack, or
  • a hypothetical instantiation of a templated entity immediately following its definition would be ill-formed due to a construct (other than a static_assert-declaration that fails) that does not depend on a template parameter, or
  • the interpretation of such a construct in the hypothetical instantiation is different from the interpretation of the corresponding construct in any actual instantiation of the templated entity.
[Note 4: 
This can happen in situations including the following:
  • a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is performed, or
  • lookup for a name in the template definition found a using-declaration, but the lookup in the corresponding scope in the instantiation does not find any declarations because the using-declaration was a pack expansion and the corresponding pack is empty, or
  • an instantiation uses a default argument or default template argument that had not been defined at the point at which the template was defined, or
  • constant expression evaluation within the template instantiation uses
    • the value of a const object of integral or unscoped enumeration type or
    • the value of a constexpr object or
    • the value of a reference or
    • the definition of a constexpr function,
    and that entity was not defined when the template was defined, or
  • a class template specialization or variable template specialization that is specified by a non-dependent simple-template-id is used by the template, and either it is instantiated from a partial specialization that was not defined when the template was defined or it names an explicit specialization that was not declared when the template was defined.
— end note]
Otherwise, no diagnostic shall be issued for a template for which a valid specialization can be generated.
[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; // diagnosed if X​::​f is instantiated, and the assignment to t is an error p = i; // may be diagnosed even if X​::​f is not instantiated p = j; // may be diagnosed even if X​::​f is not instantiated X<T>::g(t); // OK X<T>::h(); // may be diagnosed even if X​::​f is not instantiated } void g(T t) { +; // may be diagnosed even if X​::​g is not instantiated } }; template<class... T> struct A { void operator++(int, T... t); // error: too many parameters }; template<class... T> union X : T... { }; // error: union with base class template<class... T> struct A : T..., T... { }; // error: duplicate base class — end example]
[Note 6: 
For purposes of name lookup, default arguments and noexcept-specifiers of function templates and default arguments and noexcept-specifiers of member functions of class templates are considered definitions ([temp.decls]).
— end note]
123)123)
This includes friend function declarations.