Files
cppdraft_translate/cppdraft/temp/dep.md
2025-10-25 03:02:53 +03:00

830 lines
44 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.1General[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.1General[temp.dep.general]") (that is, its type may depend on a template parameter) or[*value-dependent*](#def:expression,value-dependent "13.8.3.1General[temp.dep.general]") (that is, its value when evaluated as a constant expression ([[expr.const]](expr.const "7.7Constant 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.1General[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.3Operators in expressions")),
of the form:
[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
where the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") is an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified 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.1General[expr.post.general]") is a pack
expansion ([[temp.variadic]](temp.variadic "13.7.4Variadic templates")), or
- [(2.2)](#general-2.2)
any of the expressions
or [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]")*s* in the[*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]") is [type-dependent](#expr "13.8.3.3Type-dependent expressions[temp.dep.expr]"), or
- [(2.3)](#general-2.3)
the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") is a [*template-id*](temp.names#nt:template-id "13.3Names 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.2Unqualified names[expr.prim.id.unqual]") ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified 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.3Conversion functions[class.conv.fct]") whose [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3Conversion 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.2Unqualified names[expr.prim.id.unqual]") is
the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[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.1Point 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.2Candidate 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<class T> struct X : B<T> {typename T::A* pa; void f(B<T>* pb) {static int i = B<T>::i;
pb->j++; }};
The base class nameB<T>,
the type nameT::A,
the namesB<T>::i andpb->j explicitly depend on the[*template-parameter*](temp.param#nt:template-parameter "13.2Template 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.3Names of template specializations[temp.names]") refers to the[*current instantiation*](#def:current_instantiation "13.8.3.2Dependent 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.1Preamble[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.1Preamble[temp.pre]") ([[temp.arg]](temp.arg "13.4Template 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.6Partial 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.6Local 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.11Identifiers[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.11Identifiers[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 T> class A { A* p1; // A is the current instantiation A<T>* p2; // A<T> is the current instantiation A<T*> p3; // A<T*> is not the current instantiation::A<T>* p4; // ::A<T> is the current instantiationclass B { B* p1; // B is the current instantiation A<T>::B* p2; // A<T>::B is the current instantiationtypename A<T*>::B* p3; // A<T*>::B is not the current instantiation};};
template <class T> class A<T*> { A<T*>* p1; // A<T*> is the current instantiation A<T>* p2; // A<T> is not the current instantiation};
template <class T1, class T2, int I> struct B { B<T1, T2, I>* b1; // refers to the current instantiation B<T2, T1, I>* 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<my_T1, T2, my_I>* b3; // refers to the current instantiation B<my_T1, T2, my_I2>* b4; // not the current instantiation B<my_T1, T2, my_I3>* b5; // refers to the current instantiation B<my_T1, T2, my_I4>* b6; // not the current instantiation B<my_T1, T2, my_I5>* 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.2Dependent 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<class T> struct A {typedef int M; struct B {typedef void M; struct C; };};
template<class T> struct A<T>::B::C : A<T> { M m; // OK, A<T>::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.5Qualified name lookup")) or unqualified name is a[*member of the current instantiation*](#def:current_instantiation,member_of_the "13.8.3.2Dependent 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 T> 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<T>::i]; // A<T>::i refers to a member of the current instantiationint f();};
template <class T> int A<T>::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.2Dependent 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.10The 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.5Qualified 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.3Conversion functions[class.conv.fct]") whose [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3Conversion 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.5Qualified name lookup"))[.](#type-5.sentence-1)
[*Example [4](#type-example-4)*: struct A {using B = int;
A f();};struct C : A {};template<class T>void 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;};
template<typename T>struct 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<B>::f(); // error: finds both A::m and B::mtemplate int C<B>::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.1General") — *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.1Sequential 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.1General")) 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.8Deduced 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.2Type names[dcl.name]") is dependent after
class template argument deduction ([[over.match.class.deduct]](over.match.class.deduct "12.2.2.9Class template argument deduction"))
and substitution ([[temp.alias]](temp.alias "13.7.8Alias templates"))[.](#type-8.sentence-1)
[9](#type-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5591)
[*Example [6](#type-example-6)*: template<class T, class V>struct S { S(T); };
template<class U>struct A {template<class T> using X = S<T, U>; template<class T> using Y = S<T, int>; 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.3Names 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.7Dependent 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.4Pack indexing specifier[dcl.type.pack.index]"),
- [(10.13)](#type-10.13)
denoted by decltype([*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]")),
where [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") is [type-dependent](#expr "13.8.3.3Type-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.9Type splicing[dcl.type.splice]") in which either
the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") is dependent ([[temp.dep.splice]](#splice "13.8.3.5Dependent 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.1Preamble")) of a class template
used without a [*template-argument-list*](temp.names#nt:template-argument-list "13.3Names 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.3This")) is
dependent ([[temp.dep.type]](#type "13.8.3.2Dependent 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.1General[expr.prim.id.general]") is type-dependent
if it is a [*template-id*](temp.names#nt:template-id "13.3Names 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.7Placeholder 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.7Placeholder 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.7Structured binding declarations")) whose[*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[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 <typename T>void f() { C arr[1]; auto [...e] = arr;
g(e...); // calls #2}void g(C); // #2int main() { f<int>();} — *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.3Captures"))
in a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") that has an explicit object parameter whose type is dependent ([[dcl.fct]](dcl.fct "9.3.4.6Functions")),
- [(3.8)](#expr-3.8)
the[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")__func__ ([[dcl.fct.def.general]](dcl.fct.def.general "9.6.1General")), 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.2Referring 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.3Conversion 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.1Preamble[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.7Expansion 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.5Static 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.2Type names[dcl.name]"),[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]"),[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]"),
or[*new-type-id*](expr.new#nt:new-type-id "7.6.2.8New[expr.new]") is dependent, even if any subexpression is type-dependent:
[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]")
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]")
::opt new [*new-placement*](expr.new#nt:new-placement "7.6.2.8New[expr.new]")opt [*new-type-id*](expr.new#nt:new-type-id "7.6.2.8New[expr.new]") [*new-initializer*](expr.new#nt:new-initializer "7.6.2.8New[expr.new]")opt
::opt new [*new-placement*](expr.new#nt:new-placement "7.6.2.8New[expr.new]")opt ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ) [*new-initializer*](expr.new#nt:new-initializer "7.6.2.8New[expr.new]")opt
dynamic_cast < [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
static_cast < [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
const_cast < [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
reinterpret_cast < [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ) [*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit 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.1Kinds of literals[lex.literal.kinds]")
sizeof [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1General[expr.unary.general]")
sizeof ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") )
sizeof ... ( [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") )
alignof ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") )
typeid ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
typeid ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") )
::opt delete [*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]")
::opt delete [ ] [*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]")
throw [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19Assignment and compound assignment operators[expr.assign]")opt
noexcept ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
[*requires-expression*](expr.prim.req.general#nt:requires-expression "7.5.8.1General[expr.prim.req.general]")
[*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10The reflection operator[expr.reflect]")
[*Note [1](#expr-note-1)*:
For the standard library macro offsetof,
see [[support.types]](support.types "17.2Common 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.5Class 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.1General[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.1General[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.7Fold 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.4Pack indexing expression[expr.prim.pack.index]") is type-dependent
if its [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[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.9Expression splicing[expr.prim.splice]") is type-dependent
if its [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") is dependent ([[temp.dep.splice]](#splice "13.8.3.5Dependent 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.1General[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.9Concept definitions[temp.concept]") is dependent or
any of its arguments are dependent ([[temp.dep.temp]](#temp "13.8.3.7Dependent 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.1Preamble[stmt.pre]") of an expansion statement ([[stmt.expand]](stmt.expand "8.7Expansion 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.1General[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.7Constant 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.1General[expr.unary.general]") or [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") is type-dependent or the[*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") is dependent:
sizeof [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1General[expr.unary.general]")
sizeof ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") )
typeid ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
typeid ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") )
alignof ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") )
[*Note [1](#constexpr-note-1)*:
For the standard library macro offsetof,
see [[support.types]](support.types "17.2Common 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.2Type names[dcl.name]"),[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]"), or[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]") is dependent or the[*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") or[*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]") is value-dependent or
any [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") in the [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]") is value-dependent or
any [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19Assignment and compound assignment operators[expr.assign]") in the [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]") is value-dependent:
[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]")
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1General[dcl.init.general]")
static_cast < [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
const_cast < [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
reinterpret_cast < [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
dynamic_cast < [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20Comma operator[expr.comma]") )
( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ) [*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit 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.11Identifiers[lex.name]") )
[*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7Fold expressions[expr.prim.fold]")
unless the [*identifier*](lex.name#nt:identifier "5.11Identifiers[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.7noexcept operator[expr.unary.noexcept]") ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7noexcept operator"))
is value-dependent if
its [*expression*](expr.comma#nt:expression "7.6.20Comma 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.3Qualified names[expr.prim.id.qual]") where the[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified 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.3Explicit type conversion (cast notation)[expr.cast]") is also value-dependent if evaluating [*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]") as a [core constant expression](expr.const#def:expression,core_constant "7.7Constant 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.10The 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.10The reflection operator[expr.reflect]") and
the [*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10The 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.1General[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.2Dependent types")),
- [(7.2)](#constexpr-7.2)
it is of the form ^^[*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") and
the [*type-id*](dcl.name#nt:type-id "9.3.2Type 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.1General[expr.prim.id.general]") and
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[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.9Expression splicing[expr.prim.splice]") is value-dependent
if its [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") is dependent ([[temp.dep.splice]](#splice "13.8.3.5Dependent 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.6Splice specifiers[basic.splice]") is dependent
if its converted [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") is value-dependent[.](#splice-1.sentence-1)
A [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") is dependent
if its [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice 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.3Qualified names[expr.prim.id.qual]") is dependent
if its [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice 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)*: template<auto T, auto NS>void 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 <auto V> 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<template<class> class X>struct S {[:^^X:]<int, float> m;};
template<class> struct V1 {};template<class, class = int> struct V2 {};
S<V1> s1; // error: V1<int, float> has too many template arguments S<V2> 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.3Namespace alias[namespace.alias]") whose [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3Namespace alias[namespace.alias]") (if any) is
a dependent qualified name or
whose [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") (if any) is dependent[.](#namespace-1.sentence-1)
A [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[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)*: template<std::meta::info R>int 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.3Names 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.3Names 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.3Names 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.3Names 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)