Init
This commit is contained in:
829
cppdraft/temp/dep.md
Normal file
829
cppdraft/temp/dep.md
Normal file
@@ -0,0 +1,829 @@
|
||||
[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<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.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 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.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<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.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 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.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 {};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.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)*: 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.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 <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.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)*: 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.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)*: 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.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)
|
||||
Reference in New Issue
Block a user