[temp.dep] # 13 Templates [[temp]](./#temp) ## 13.8 Name resolution [[temp.res]](temp.res#temp.dep) ### 13.8.3 Dependent names [temp.dep] #### [13.8.3.1](#general) General [[temp.dep.general]](temp.dep.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5268) Inside a template, some constructs have semantics which may differ from one instantiation to another[.](#general-1.sentence-1) Such a construct[*depends*](#def:name,dependent "13.8.3.1 General [temp.dep.general]") on the template parameters[.](#general-1.sentence-2) In particular, types and expressions may depend on the type and/or value of template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names[.](#general-1.sentence-3) An expression may be[*type-dependent*](#def:expression,type-dependent "13.8.3.1 General [temp.dep.general]") (that is, its type may depend on a template parameter) or[*value-dependent*](#def:expression,value-dependent "13.8.3.1 General [temp.dep.general]") (that is, its value when evaluated as a constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) may depend on a template parameter) as described below[.](#general-1.sentence-4) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5288) A [*dependent call*](#def:call,dependent "13.8.3.1 General [temp.dep.general]") is an expression, possibly formed as a non-member candidate for an operator ([[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions")), of the form: [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt ) where the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") is an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") and - [(2.1)](#general-2.1) any of the expressions in the [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")), or - [(2.2)](#general-2.2) any of the expressions or [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")*s* in the[*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") is [type-dependent](#expr "13.8.3.3 Type-dependent expressions [temp.dep.expr]"), or - [(2.3)](#general-2.3) the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") is a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") in which any of the template arguments depends on a template parameter[.](#general-2.sentence-1) The component name of an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")) is dependent if - [(2.4)](#general-2.4) it is a [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") whose [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]") is dependent, or - [(2.5)](#general-2.5) it is operator= and the current class is a templated entity, or - [(2.6)](#general-2.6) the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") is the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") in a dependent call[.](#general-2.sentence-2) [*Note [1](#general-note-1)*: Such names are looked up only at the point of the template instantiation ([[temp.point]](temp.point "13.8.4.1 Point of instantiation")) in both the context of the template definition and the context of the point of instantiation ([[temp.dep.candidate]](temp.dep.candidate "13.8.4.2 Candidate functions"))[.](#general-2.sentence-3) — *end note*] [3](#general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5332) [*Example [1](#general-example-1)*: template struct X : B {typename T::A* pa; void f(B* pb) {static int i = B::i; pb->j++; }}; The base class nameB, the type nameT​::​A, the namesB​::​i andpb->j explicitly depend on the[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")[.](#general-3.sentence-1) — *end example*] #### [13.8.3.2](#type) Dependent types [[temp.dep.type]](temp.dep.type) [1](#type-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5358) A name or [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") refers to the[*current instantiation*](#def:current_instantiation "13.8.3.2 Dependent types [temp.dep.type]") if it is - [(1.1)](#type-1.1) in the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, the [injected-class-name](class.pre#def:injected-class-name "11.1 Preamble [class.pre]") of the class template or nested class, - [(1.2)](#type-1.2) in the definition of a primary class template or a member of a primary class template, the name of the class template followed by the template argument list of its [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") ([[temp.arg]](temp.arg "13.4 Template arguments")) enclosed in<> (or an equivalent template alias specialization), - [(1.3)](#type-1.3) in the definition of a nested class of a class template, the name of the nested class referenced as a member of the current instantiation, - [(1.4)](#type-1.4) in the definition of a class template partial specialization or a member of a class template partial specialization, the name of the class template followed by a template argument list equivalent to that of the partial specialization ([[temp.spec.partial]](temp.spec.partial "13.7.6 Partial specialization")) enclosed in <> (or an equivalent template alias specialization), or - [(1.5)](#type-1.5) in the definition of a templated function, the name of a local class ([[class.local]](class.local "11.6 Local class declarations"))[.](#type-1.sentence-1) [2](#type-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5388) A template argument that is equivalent to a template parameter can be used in place of that template parameter in a reference to the current instantiation[.](#type-2.sentence-1) A template argument is equivalent to a type template parameter if it denotes the same type[.](#type-2.sentence-2) A template argument is equivalent to a constant template parameter if it is an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that names a variable that is equivalent to the template parameter[.](#type-2.sentence-3) A variable is equivalent to a template parameter if - [(2.1)](#type-2.1) it has the same type as the template parameter (ignoring cv-qualification) and - [(2.2)](#type-2.2) its initializer consists of a single [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that names the template parameter or, recursively, such a variable[.](#type-2.sentence-4) [*Note [1](#type-note-1)*: Using a parenthesized variable name breaks the equivalence[.](#type-2.sentence-5) — *end note*] [*Example [1](#type-example-1)*: template class A { A* p1; // A is the current instantiation A* p2; // A is the current instantiation A p3; // A is not the current instantiation::A* p4; // ​::​A is the current instantiationclass B { B* p1; // B is the current instantiation A::B* p2; // A​::​B is the current instantiationtypename A::B* p3; // A​::​B is not the current instantiation};}; template class A { A* p1; // A is the current instantiation A* p2; // A is not the current instantiation}; template struct B { B* b1; // refers to the current instantiation B* b2; // not the current instantiationtypedef T1 my_T1; static const int my_I = I; static const int my_I2 = I+0; static const int my_I3 = my_I; static const long my_I4 = I; static const int my_I5 = (I); B* b3; // refers to the current instantiation B* b4; // not the current instantiation B* b5; // refers to the current instantiation B* b6; // not the current instantiation B* b7; // not the current instantiation}; — *end example*] [3](#type-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5446) A [*dependent base class*](#def:base_class,dependent "13.8.3.2 Dependent types [temp.dep.type]") is a base class that is a dependent type and is not the current instantiation[.](#type-3.sentence-1) [*Note [2](#type-note-2)*: A base class can be the current instantiation in the case of a nested class naming an enclosing class as a base[.](#type-3.sentence-2) [*Example [2](#type-example-2)*: template struct A {typedef int M; struct B {typedef void M; struct C; };}; template struct A::B::C : A { M m; // OK, A​::​M}; — *end example*] — *end note*] [4](#type-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5470) A qualified ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")) or unqualified name is a[*member of the current instantiation*](#def:current_instantiation,member_of_the "13.8.3.2 Dependent types [temp.dep.type]") if - [(4.1)](#type-4.1) its lookup context, if it is a qualified name, is the current instantiation, and - [(4.2)](#type-4.2) lookup for it finds any member of a class that is the current instantiation [*Example [3](#type-example-3)*: template class A {static const int i = 5; int n1[i]; // i refers to a member of the current instantiationint n2[A::i]; // A​::​i refers to a member of the current instantiationint n3[A::i]; // A​::​i refers to a member of the current instantiationint f();}; template int A::f() {return i; // i refers to a member of the current instantiation} — *end example*] A qualified or unqualified name names a [*dependent member of the current instantiation*](#def:current_instantiation,dependent_member_of_the "13.8.3.2 Dependent types [temp.dep.type]") if it is a member of the current instantiation that, when looked up, refers to at least one member declaration (including a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") whose terminal name is dependent) of a class that is the current instantiation[.](#type-4.sentence-2) [5](#type-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5505) A qualified name ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")) is dependent if - [(5.1)](#type-5.1) it is a [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") whose [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]") is dependent, or - [(5.2)](#type-5.2) its lookup context is dependent and is not the current instantiation, or - [(5.3)](#type-5.3) its lookup context is the current instantiation and it is operator=,[117](#footnote-117 "Every instantiation of a class template declares a different set of assignment operators.") or - [(5.4)](#type-5.4) its lookup context is the current instantiation and has at least one dependent base class, and qualified name lookup for the name finds nothing ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup"))[.](#type-5.sentence-1) [*Example [4](#type-example-4)*: struct A {using B = int; A f();};struct C : A {};templatevoid g(T t) {decltype(t.A::f())::B i; // error: typename needed to interpret B as a type}template void g(C); // …even though A is ​::​A here — *end example*] [6](#type-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5541) If, for a given set of template arguments, a specialization of a template is instantiated that refers to a member of the current instantiation with a qualified name, the name is looked up in the template instantiation context[.](#type-6.sentence-1) If the result of this lookup differs from the result of name lookup in the template definition context, name lookup is ambiguous[.](#type-6.sentence-2) [*Example [5](#type-example-5)*: struct A {int m;}; struct B {int m;}; templatestruct C : A, T {int f() { return this->m; } // finds A​::​m in the template definition contextint g() { return m; } // finds A​::​m in the template definition context}; template int C::f(); // error: finds both A​::​m and B​::​mtemplate int C::g(); // OK, transformation to class member access syntax// does not occur in the template definition context; see [[expr.prim.id.general]](expr.prim.id.general "7.5.5.1 General") — *end example*] [7](#type-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5570) An initializer is dependent if any constituent expression ([[intro.execution]](intro.execution "6.10.1 Sequential execution")) of the initializer is type-dependent[.](#type-7.sentence-1) A placeholder type ([[dcl.spec.auto.general]](dcl.spec.auto.general "9.2.9.7.1 General")) is dependent if it designates a type deduced from a dependent initializer[.](#type-7.sentence-2) [8](#type-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5577) A placeholder for a deduced class type ([[dcl.type.class.deduct]](dcl.type.class.deduct "9.2.9.8 Deduced class template specialization types")) is dependent if - [(8.1)](#type-8.1) it has a dependent initializer, or - [(8.2)](#type-8.2) it refers to an alias template that is a member of the current instantiation and whose [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") is dependent after class template argument deduction ([[over.match.class.deduct]](over.match.class.deduct "12.2.2.9 Class template argument deduction")) and substitution ([[temp.alias]](temp.alias "13.7.8 Alias templates"))[.](#type-8.sentence-1) [9](#type-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5591) [*Example [6](#type-example-6)*: templatestruct S { S(T); }; templatestruct A {template using X = S; template using Y = S; void f() {new X(1); // dependentnew Y(1); // not dependent}}; — *end example*] [10](#type-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5609) A type is dependent if it is - [(10.1)](#type-10.1) a template parameter, - [(10.2)](#type-10.2) denoted by a dependent (qualified) name, - [(10.3)](#type-10.3) a nested class or enumeration that is a direct member of a class that is the current instantiation, - [(10.4)](#type-10.4) a cv-qualified type where the cv-unqualified type is dependent, - [(10.5)](#type-10.5) a compound type constructed from any dependent type, - [(10.6)](#type-10.6) an array type whose element type is dependent or whose bound (if any) is value-dependent, - [(10.7)](#type-10.7) a function type whose parameters include one or more function parameter packs, - [(10.8)](#type-10.8) a function type whose exception specification is value-dependent, - [(10.9)](#type-10.9) denoted by a dependent placeholder type, - [(10.10)](#type-10.10) denoted by a dependent placeholder for a deduced class type, - [(10.11)](#type-10.11) denoted by a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") in which either the template name is a template parameter or any of the template arguments is dependent ([[temp.dep.temp]](#temp "13.8.3.7 Dependent template arguments")),[118](#footnote-118 "This includes an injected-class-name ([class.pre]) of a class template used without a template-argument-list.") - [(10.12)](#type-10.12) a [*pack-index-specifier*](dcl.type.pack.index#nt:pack-index-specifier "9.2.9.4 Pack indexing specifier [dcl.type.pack.index]"), - [(10.13)](#type-10.13) denoted by decltype([*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]")), where [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") is [type-dependent](#expr "13.8.3.3 Type-dependent expressions [temp.dep.expr]"), or - [(10.14)](#type-10.14) denoted by a [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9 Type splicing [dcl.type.splice]") in which either the [*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]") is dependent ([[temp.dep.splice]](#splice "13.8.3.5 Dependent splice specifiers"))[.](#type-10.sentence-1) [11](#type-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5651) [*Note [3](#type-note-3)*: Because typedefs do not introduce new types, but instead simply refer to other types, a name that refers to a typedef that is a member of the current instantiation is dependent only if the type referred to is dependent[.](#type-11.sentence-1) — *end note*] [117)](#footnote-117)[117)](#footnoteref-117) Every instantiation of a class template declares a different set of assignment operators[.](#footnote-117.sentence-1) [118)](#footnote-118)[118)](#footnoteref-118) This includes an injected-class-name ([[class.pre]](class.pre "11.1 Preamble")) of a class template used without a [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]")[.](#footnote-118.sentence-1) #### [13.8.3.3](#expr) Type-dependent expressions [[temp.dep.expr]](temp.dep.expr) [1](#expr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5661) Except as described below, an expression is type-dependent if any subexpression is type-dependent[.](#expr-1.sentence-1) [2](#expr-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5665) this is type-dependent if the current class ([[expr.prim.this]](expr.prim.this "7.5.3 This")) is dependent ([[temp.dep.type]](#type "13.8.3.2 Dependent types"))[.](#expr-2.sentence-1) [3](#expr-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5670) An [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is type-dependent if it is a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") that is not a concept-id and is dependent; or if its terminal name is - [(3.1)](#expr-3.1) associated by name lookup with one or more declarations declared with a dependent type, - [(3.2)](#expr-3.2) associated by name lookup with a constant template parameter declared with a type that contains a placeholder type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers")), - [(3.3)](#expr-3.3) associated by name lookup with a variable declared with a type that contains a placeholder type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers")) where the initializer is type-dependent, - [(3.4)](#expr-3.4) associated by name lookup with one or more declarations of member functions of a class that is the current instantiation declared with a return type that contains a placeholder type, - [(3.5)](#expr-3.5) associated by name lookup with a structured binding declaration ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations")) whose[*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") is type-dependent, - [(3.6)](#expr-3.6) associated by name lookup with a pack, [*Example [1](#expr-example-1)*: struct C { }; void g(...); // #1template void f() { C arr[1]; auto [...e] = arr; g(e...); // calls #2}void g(C); // #2int main() { f();} — *end example*] - [(3.7)](#expr-3.7) associated by name lookup with an entity captured by copy ([[expr.prim.lambda.capture]](expr.prim.lambda.capture "7.5.6.3 Captures")) in a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") that has an explicit object parameter whose type is dependent ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")), - [(3.8)](#expr-3.8) the[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")__func__ ([[dcl.fct.def.general]](dcl.fct.def.general "9.6.1 General")), where any enclosing function is a template, a member of a class template, or a generic lambda, - [(3.9)](#expr-3.9) associated by name lookup with a result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2 Referring to the result object")) of a function whose return type is dependent, - [(3.10)](#expr-3.10) a [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") that specifies a dependent type, - [(3.11)](#expr-3.11) a name N introduced by the [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") of an expansion statement S if the type specified for N contains a placeholder type and either * [(3.11.1)](#expr-3.11.1) the [*expansion-initializer*](stmt.expand#nt:expansion-initializer "8.7 Expansion statements [stmt.expand]") of S is type-dependent or * [(3.11.2)](#expr-3.11.2) S is not an iterating expansion statement, or - [(3.12)](#expr-3.12) dependent or if it names a dependent member of the current instantiation that is a static data member of type “array of unknown bound of T” for some T ([[temp.static]](temp.static "13.7.2.5 Static data members of class templates"))[.](#expr-3.sentence-1) Expressions of the following forms are type-dependent only if the type specified by the[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]"),[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]"),[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]"), or[*new-type-id*](expr.new#nt:new-type-id "7.6.2.8 New [expr.new]") is dependent, even if any subexpression is type-dependent: [*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt ) [*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt ) [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") ::opt new [*new-placement*](expr.new#nt:new-placement "7.6.2.8 New [expr.new]")opt [*new-type-id*](expr.new#nt:new-type-id "7.6.2.8 New [expr.new]") [*new-initializer*](expr.new#nt:new-initializer "7.6.2.8 New [expr.new]")opt ::opt new [*new-placement*](expr.new#nt:new-placement "7.6.2.8 New [expr.new]")opt ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) [*new-initializer*](expr.new#nt:new-initializer "7.6.2.8 New [expr.new]")opt dynamic_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) static_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) const_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) reinterpret_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") [4](#expr-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5769) Expressions of the following forms are never type-dependent (because the type of the expression cannot be dependent): [*literal*](lex.literal.kinds#nt:literal "5.13.1 Kinds of literals [lex.literal.kinds]") sizeof [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]") sizeof ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) sizeof ... ( [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ) alignof ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) typeid ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) typeid ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) ::opt delete [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") ::opt delete [ ] [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") throw [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19 Assignment and compound assignment operators [expr.assign]")opt noexcept ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) [*requires-expression*](expr.prim.req.general#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") [*Note [1](#expr-note-1)*: For the standard library macro offsetof, see [[support.types]](support.types "17.2 Common definitions")[.](#expr-4.sentence-2) — *end note*] [5](#expr-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5793) A [class member access expression](expr.ref "7.6.1.5 Class member access [expr.ref]") is type-dependent if the terminal name of its [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]"), if any, is dependent or the expression refers to a member of the current instantiation and the type of the referenced member is dependent[.](#expr-5.sentence-1) [*Note [2](#expr-note-2)*: In an expression of the formx.y orxp->y the type of the expression is usually the type of the membery of the class ofx (or the class pointed to byxp)[.](#expr-5.sentence-2) However, ifx orxp refers to a dependent type that is not the current instantiation, the type ofy is always dependent[.](#expr-5.sentence-3) — *end note*] [6](#expr-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5820) A [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") is type-dependent if any element is type-dependent or is a pack expansion[.](#expr-6.sentence-1) [7](#expr-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5824) A [*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") is type-dependent[.](#expr-7.sentence-1) [8](#expr-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5827) A [*pack-index-expression*](expr.prim.pack.index#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") is type-dependent if its [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is type-dependent[.](#expr-8.sentence-1) [9](#expr-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5831) A [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") is type-dependent if its [*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]") is dependent ([[temp.dep.splice]](#splice "13.8.3.5 Dependent splice specifiers"))[.](#expr-9.sentence-1) #### [13.8.3.4](#constexpr) Value-dependent expressions [[temp.dep.constexpr]](temp.dep.constexpr) [1](#constexpr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5839) Except as described below, an expression used in a context where a constant expression is required is value-dependent if any subexpression is value-dependent[.](#constexpr-1.sentence-1) [2](#constexpr-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5844) An[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is value-dependent if - [(2.1)](#constexpr-2.1) it is a concept-id and its [*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept definitions [temp.concept]") is dependent or any of its arguments are dependent ([[temp.dep.temp]](#temp "13.8.3.7 Dependent template arguments")), - [(2.2)](#constexpr-2.2) it is type-dependent, - [(2.3)](#constexpr-2.3) it is the name of a constant template parameter, - [(2.4)](#constexpr-2.4) it is a name introduced by the [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") of an expansion statement ([[stmt.expand]](stmt.expand "8.7 Expansion statements")), - [(2.5)](#constexpr-2.5) it names a static data member that is a dependent member of the current instantiation and is not initialized in a [*member-declarator*](class.mem.general#nt:member-declarator "11.4.1 General [class.mem.general]"), - [(2.6)](#constexpr-2.6) it names a static member function that is a dependent member of the current instantiation, or - [(2.7)](#constexpr-2.7) it names a potentially-constant variable ([[expr.const]](expr.const "7.7 Constant expressions")) that is initialized with an expression that is value-dependent[.](#constexpr-2.sentence-1) Expressions of the following form are value-dependent if the[*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]") or [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") is type-dependent or the[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") is dependent: sizeof [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]") sizeof ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) typeid ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) typeid ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) alignof ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) [*Note [1](#constexpr-note-1)*: For the standard library macro offsetof, see [[support.types]](support.types "17.2 Common definitions")[.](#constexpr-2.sentence-3) — *end note*] [3](#constexpr-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5889) Expressions of the following form are value-dependent if either the[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]"),[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]"), or[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") is dependent or the[*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") or[*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") is value-dependent or any [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") in the [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") is value-dependent or any [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19 Assignment and compound assignment operators [expr.assign]") in the [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") is value-dependent: [*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt ) [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt ) [*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") static_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) const_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) reinterpret_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) dynamic_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") [4](#constexpr-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5915) Expressions of the following form are value-dependent: sizeof ... ( [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ) [*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") unless the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is a structured binding pack whose initializer is not dependent[.](#constexpr-4.sentence-1) [5](#constexpr-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5924) A [*noexcept-expression*](expr.unary.noexcept#nt:noexcept-expression "7.6.2.7 noexcept operator [expr.unary.noexcept]") ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator")) is value-dependent if its [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") involves a template parameter[.](#constexpr-5.sentence-1) [6](#constexpr-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5929) An expression of the form &[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") where the[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") names a dependent member of the current instantiation is value-dependent[.](#constexpr-6.sentence-1) An expression of the form &[*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") is also value-dependent if evaluating [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") as a [core constant expression](expr.const#def:expression,core_constant "7.7 Constant expressions [expr.const]") succeeds and the result of the evaluation refers to a templated entity that is an object with static or thread storage duration or a member function[.](#constexpr-6.sentence-2) [7](#constexpr-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5939) A [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") is value-dependent if - [(7.1)](#constexpr-7.1) it is of the form ^^[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]") and the [*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]") * [(7.1.1)](#constexpr-7.1.1) is a dependent qualified name, * [(7.1.2)](#constexpr-7.1.2) is a dependent [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"), * [(7.1.3)](#constexpr-7.1.3) is the name of a template parameter, or * [(7.1.4)](#constexpr-7.1.4) names a dependent member of the current instantiation ([[temp.dep.type]](#type "13.8.3.2 Dependent types")), - [(7.2)](#constexpr-7.2) it is of the form ^^[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") and the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") denotes a dependent type, or - [(7.3)](#constexpr-7.3) it is of the form ^^[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") and the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is value-dependent[.](#constexpr-7.sentence-1) [8](#constexpr-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5959) A [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") is value-dependent if its [*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]") is dependent ([[temp.dep.splice]](#splice "13.8.3.5 Dependent splice specifiers"))[.](#constexpr-8.sentence-1) #### [13.8.3.5](#splice) Dependent splice specifiers [[temp.dep.splice]](temp.dep.splice) [1](#splice-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5967) A [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") is dependent if its converted [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") is value-dependent[.](#splice-1.sentence-1) A [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") is dependent if its [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") is dependent or if any of its template arguments are dependent[.](#splice-1.sentence-2) A [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") is dependent if its [*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]") is dependent[.](#splice-1.sentence-3) [2](#splice-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5977) [*Example [1](#splice-example-1)*: templatevoid fn() {using a = [:T:]<1>; // [:T:]<1> is dependent because [:T:] is dependentstatic_assert([:NS:]::template TCls<1>::v == a::v); // [:NS:] is dependent}namespace N {template struct TCls { static constexpr int v = V; };}int main() { fn<^^N::TCls, ^^N>();} — *end example*] [3](#splice-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5996) [*Example [2](#splice-example-2)*: template class X>struct S {[:^^X:] m;}; template struct V1 {};template struct V2 {}; S s1; // error: V1 has too many template arguments S s2; // OK — *end example*] #### [13.8.3.6](#namespace) Dependent namespaces [[temp.dep.namespace]](temp.dep.namespace) [1](#namespace-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6014) A namespace alias is dependent if it is introduced by a [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3 Namespace alias [namespace.alias]") whose [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3 Namespace alias [namespace.alias]") (if any) is a dependent qualified name or whose [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") (if any) is dependent[.](#namespace-1.sentence-1) A [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") is dependent if it names a dependent namespace alias[.](#namespace-1.sentence-2) [2](#namespace-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6023) [*Example [1](#namespace-example-1)*: templateint fn() {namespace Alias = [:R:]; // [:R:] is dependentreturn typename Alias::T{}; // Alias is dependent}namespace NS {using T = int;}int a = fn<^^NS>(); — *end example*] #### [13.8.3.7](#temp) Dependent template arguments [[temp.dep.temp]](temp.dep.temp) [1](#temp-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6042) A type[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is dependent if the type it specifies is dependent[.](#temp-1.sentence-1) [2](#temp-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6047) A constant[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is dependent if its type is dependent or the constant expression it specifies is value-dependent[.](#temp-2.sentence-1) [3](#temp-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6053) Furthermore, a constant[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is dependent if the corresponding constant template parameter is of reference or pointer type and the [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") designates or points to a member of the current instantiation or a member of a dependent type[.](#temp-3.sentence-1) [4](#temp-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6061) A template argument is also dependent if it is a pack expansion[.](#temp-4.sentence-1) [5](#temp-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6065) A template template parameter is dependent if it names a template parameter or its terminal name is dependent[.](#temp-5.sentence-1)