[temp.res.general] # 13 Templates [[temp]](./#temp) ## 13.8 Name resolution [[temp.res]](temp.res#general) ### 13.8.1 General [temp.res.general] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4754) 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[.](#1.sentence-1) If the name is dependent (as specified in [[temp.dep]](temp.dep "13.8.3 Dependent names")), it is looked up for each specialization (after substitution) because the lookup depends on a template parameter[.](#1.sentence-2) [*Note [1](#note-1)*: Some dependent names are also looked up during parsing to determine that they are dependent or to interpret following < tokens[.](#1.sentence-3) Uses of other names might be type-dependent or value-dependent ([[temp.dep.expr]](temp.dep.expr "13.8.3.3 Type-dependent expressions"), [[temp.dep.constexpr]](temp.dep.constexpr "13.8.3.4 Value-dependent expressions"))[.](#1.sentence-4) A [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") is never dependent in a specialization and is therefore replaced during lookup for that specialization ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#1.sentence-5) — *end note*] [*Example [1](#example-1)*: struct A { operator int(); };templatestruct D : B { T get() { return operator T(); } // [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") is dependent};int f(D d) { return d.get(); } // OK, lookup finds A​::​operator int — *end example*] [*Example [2](#example-2)*: void f(char); template 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](#example-3)*: struct A {struct B { /* ... */ }; int a; int Y;}; int a; template struct Y : T {struct B { /* ... */ }; B b; // The B defined in Yvoid f(int i) { a = i; } // ​::​a Y* p; // Y}; Y ya; The members A​::​B, A​::​a, and A​::​Y of the template argument A do not affect the binding of names in Y[.](#1.sentence-6) — *end example*] [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4828) 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]](temp.point "13.8.4.1 Point of instantiation")) but is not found by lookup for the specialization, the program is ill-formed, no diagnostic required[.](#2.sentence-1) [typename-specifier:](#nt:typename-specifier "13.8.1 General [temp.res.general]") typename [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") typename [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4842) The component names of a [*typename-specifier*](#nt:typename-specifier "13.8.1 General [temp.res.general]") are its [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") (if any) and those of its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") (if any)[.](#3.sentence-1) A [*typename-specifier*](#nt:typename-specifier "13.8.1 General [temp.res.general]") denotes the type or class template denoted by the [*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ([[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers")) formed by omitting the keyword typename[.](#3.sentence-2) [*Note [2](#note-2)*: The usual qualified name lookup ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")) applies even in the presence of typename[.](#3.sentence-3) — *end note*] [*Example [4](#example-4)*: struct A {struct X { }; int X;};struct B {struct X { };};template 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*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4877) A [*type-only context*](#def:context,type-only "13.8.1 General [temp.res.general]") is defined as follows: A qualified or unqualified name is said to be in a type-only context if it is the terminal name of - [(4.1)](#4.1) a[*typename-specifier*](#nt:typename-specifier "13.8.1 General [temp.res.general]"),[*type-requirement*](expr.prim.req.type#nt:type-requirement "7.5.8.3 Type requirements [expr.prim.req.type]"),[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"),[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1 General [class.derived.general]"),[*using-enum-declarator*](enum.udecl#nt:using-enum-declarator "9.8.2 The using enum declaration [enum.udecl]"), or - [(4.2)](#4.2) a [*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") of a [*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1 General [class.mem.general]"), or - [(4.3)](#4.3) a [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1 General [dcl.type.general]") of a * [(4.3.1)](#4.3.1) [*new-type-id*](expr.new#nt:new-type-id "7.6.2.8 New [expr.new]"), * [(4.3.2)](#4.3.2) [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]"), * [(4.3.3)](#4.3.3) [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]"), * [(4.3.4)](#4.3.4) [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]"), * [(4.3.5)](#4.3.5) default argument of a [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]"), or * [(4.3.6)](#4.3.6) [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") of astatic_cast,const_cast,reinterpret_cast, ordynamic_cast, or - [(4.4)](#4.4) a [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1 General [dcl.spec.general]") of the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") of a * [(4.4.1)](#4.4.1) [*simple-declaration*](dcl.pre#nt:simple-declaration "9.1 Preamble [dcl.pre]") or [*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1 General [dcl.fct.def.general]") in namespace scope, * [(4.4.2)](#4.4.2) [*member-declaration*](class.mem.general#nt:member-declaration "11.4.1 General [class.mem.general]"), * [(4.4.3)](#4.4.3) [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") in a [*member-declaration*](class.mem.general#nt:member-declaration "11.4.1 General [class.mem.general]"),[116](#footnote-116 "This includes friend function declarations.") unless that [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") appears in a default argument, * [(4.4.4)](#4.4.4) [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") in a [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") of a function or function template declaration whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is qualified, unless that [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") appears in a default argument, * [(4.4.5)](#4.4.5) [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") in a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") or [*requirement-parameter-list*](expr.prim.req.general#nt:requirement-parameter-list "7.5.8.1 General [expr.prim.req.general]"), unless that [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") appears in a default argument, or * [(4.4.6)](#4.4.6) [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") of a [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]") (which necessarily declares a constant template parameter)[.](#4.sentence-1) A [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") ([[basic.splice]](basic.splice "6.6 Splice specifiers")) is said to be in a type-only context if a hypothetical qualified name appearing in the same position would be in a type-only context[.](#4.sentence-2) [*Example [5](#example-5)*: template T::R f(); // OK, return type of a function declaration at global scopetemplate void f(T::R); // ill-formed, no diagnostic required: attempt to declare// a void variable templateenum class Enum { A, B, C };template struct S {using Ptr = PtrTraits::Ptr; // OK, in a [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]")using Alias = [:^^int:]; // OK, in a [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") T::R f(T::P p) { // OK, class scopereturn static_cast(p); // OK, [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") of a static_cast}auto g() -> S::Ptr; // OK, [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")auto h() -> [:^^S:]; // OK, [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")using enum [:^^Enum:]; // OK, [*using-enum-declarator*](enum.udecl#nt:using-enum-declarator "9.8.2 The using enum declaration [enum.udecl]")};template void f() {void (*pf)(T::X); // variable pf of type void* initialized with T​::​Xvoid g(T::X); // error: T​::​X at block scope does not denote a type// (attempt to declare a void variable)} — *end example*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4957) A [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") whose terminal name is dependent and that is in a type-only context is considered to denote a type[.](#5.sentence-1) A name that refers to a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") whose terminal name is dependent is interpreted as a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") if the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") uses the keyword typename[.](#5.sentence-2) [*Example [6](#example-6)*: template 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(1); // OK f(1); // error: Foo​::​x is a type} — *end example*] [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4986) The validity of a templated entity may be checked prior to any instantiation[.](#6.sentence-1) [*Note [3](#note-3)*: Knowing which names are type names allows the syntax of every template to be checked in this way[.](#6.sentence-2) — *end note*] The program is ill-formed, no diagnostic required, if - [(6.1)](#6.1) no valid specialization, ignoring [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]")s that fail ([[dcl.pre]](dcl.pre "9.1 Preamble")), can be generated for a templated entity or a substatement of a constexpr if statement ([[stmt.if]](stmt.if "8.5.2 The if statement")) within a templated entity and the innermost enclosing template is not instantiated, or - [(6.2)](#6.2) no valid specialization, ignoring [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]")s that fail, can be generated for the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of an expansion statement and there is no instantiation of it, or - [(6.3)](#6.3) no valid specialization, ignoring [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]")s that fail, can be generated for a default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") and the default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is not used in any instantiation, or - [(6.4)](#6.4) no specialization of an alias template ([[temp.alias]](temp.alias "13.7.8 Alias templates")) is valid and no specialization of the alias template is named in the program, or - [(6.5)](#6.5) any [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") 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 - [(6.6)](#6.6) every valid specialization of a variadic template requires an empty template parameter pack, or - [(6.7)](#6.7) 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*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]") that fails) that does not depend on a template parameter, or - [(6.8)](#6.8) 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[.](#6.sentence-3) [*Note [4](#note-4)*: This can happen in situations including the following: - [(6.9)](#6.9) 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 - [(6.10)](#6.10) lookup for a name in the template definition found a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]"), but the lookup in the corresponding scope in the instantiation does not find any declarations because the [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") was a pack expansion and the corresponding pack is empty, or - [(6.11)](#6.11) 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 - [(6.12)](#6.12) [constant expression evaluation](expr.const "7.7 Constant expressions [expr.const]") within the template instantiation uses * [(6.12.1)](#6.12.1) the value of a const object of integral or unscoped enumeration type or * [(6.12.2)](#6.12.2) the value of a constexpr object or * [(6.12.3)](#6.12.3) the value of a reference or * [(6.12.4)](#6.12.4) the definition of a constexpr function, and that entity was not defined when the template was defined, or - [(6.13)](#6.13) a class template specialization or variable template specialization that is specified by a non-dependent [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") 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[.](#6.sentence-4) — *end note*] [*Note [5](#note-5)*: If a template is instantiated, errors will be diagnosed according to the other rules in this document[.](#6.sentence-5) Exactly when these errors are diagnosed is a quality of implementation issue[.](#6.sentence-6) — *end note*] [*Example [7](#example-7)*: int j;template 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::g(t); // OK X::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 struct A {void operator++(int, T... t); // error: too many parameters};template union X : T... { }; // error: union with base classtemplate struct A : T..., T... { }; // error: duplicate base class — *end example*] [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5100) [*Note [6](#note-6)*: For purposes of name lookup, default arguments and[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")*s* of function templates and default arguments and [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")*s* of member functions of class templates are considered definitions ([[temp.decls]](temp.decls "13.7 Template declarations"))[.](#7.sentence-1) — *end note*] [116)](#footnote-116)[116)](#footnoteref-116) This includes friend function declarations[.](#footnote-116.sentence-1)