371 lines
21 KiB
Markdown
371 lines
21 KiB
Markdown
[temp.variadic]
|
||
|
||
# 13 Templates [[temp]](./#temp)
|
||
|
||
## 13.7 Template declarations [[temp.decls]](temp.decls#temp.variadic)
|
||
|
||
### 13.7.4 Variadic templates [temp.variadic]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3082)
|
||
|
||
A [*template parameter pack*](#def:template_parameter_pack "13.7.4 Variadic templates [temp.variadic]") is a template parameter
|
||
that accepts zero or more template arguments[.](#1.sentence-1)
|
||
|
||
[*Example [1](#example-1)*: template<class ... Types> struct Tuple { };
|
||
|
||
Tuple<> t0; // Types contains no arguments Tuple<int> t1; // Types contains one argument: int Tuple<int, float> t2; // Types contains two arguments: int and float Tuple<0> error; // error: 0 is not a type â *end example*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3096)
|
||
|
||
A [*function parameter pack*](#def:function_parameter_pack "13.7.4 Variadic templates [temp.variadic]") is a function parameter
|
||
that accepts zero or more function arguments[.](#2.sentence-1)
|
||
|
||
[*Example [2](#example-2)*: template<class ... Types> void f(Types ... args);
|
||
|
||
f(); // args contains no arguments f(1); // args contains one argument: int f(2, 1.0); // args contains two arguments: int and double â *end example*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3109)
|
||
|
||
An [](#def:init-capture_pack "13.7.4 Variadic templates [temp.variadic]")*[*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack* is a lambda capture that introduces an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") for each of the elements in the pack expansion of its [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]")[.](#3.sentence-1)
|
||
|
||
[*Example [3](#example-3)*: template <typename... Args>void foo(Args... args) {[...xs=args]{ bar(xs...); // xs is an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack};} foo(); // xs contains zero [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")*s* foo(1); // xs contains one [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") â *end example*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3127)
|
||
|
||
A [*structured binding pack*](#def:structured_binding_pack "13.7.4 Variadic templates [temp.variadic]") is an [*sb-identifier*](dcl.pre#nt:sb-identifier "9.1 Preamble [dcl.pre]") that introduces zero or more structured bindings ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations"))[.](#4.sentence-1)
|
||
|
||
[*Example [4](#example-4)*: auto foo() -> int(&)[2];
|
||
|
||
template <class T>void g() {auto [...a] = foo(); // a is a structured binding pack containing two elementsauto [b, c, ...d] = foo(); // d is a structured binding pack containing zero elements} â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3142)
|
||
|
||
A [*pack*](#def:pack "13.7.4 Variadic templates [temp.variadic]") is
|
||
a template parameter pack,
|
||
a function parameter pack,
|
||
an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack, or
|
||
a structured binding pack[.](#5.sentence-1)
|
||
|
||
The number of elements of a template parameter pack
|
||
or a function parameter pack
|
||
is the number of arguments provided for the parameter pack[.](#5.sentence-2)
|
||
|
||
The number of elements of an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack
|
||
is the number of elements in the pack expansion of its [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]")[.](#5.sentence-3)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3154)
|
||
|
||
A [*pack expansion*](#def:pack_expansion "13.7.4 Variadic templates [temp.variadic]") consists of a [*pattern*](#def:pack_expansion,pattern "13.7.4 Variadic templates [temp.variadic]") and an ellipsis, the instantiation of which
|
||
produces zero or more instantiations of the pattern in a list (described below)[.](#6.sentence-1)
|
||
|
||
The form of the pattern
|
||
depends on the context in which the expansion occurs[.](#6.sentence-2)
|
||
|
||
Pack
|
||
expansions can occur in the following contexts:
|
||
|
||
- [(6.1)](#6.1)
|
||
|
||
In a function parameter pack ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")); the pattern is the[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") without the ellipsis[.](#6.1.sentence-1)
|
||
|
||
- [(6.2)](#6.2)
|
||
|
||
In a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The using declaration"));
|
||
the pattern is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]")[.](#6.2.sentence-1)
|
||
|
||
- [(6.3)](#6.3)
|
||
|
||
In a [*friend-type-declaration*](class.mem.general#nt:friend-type-declaration "11.4.1 General [class.mem.general]") ([[class.mem.general]](class.mem.general "11.4.1 General"));
|
||
the pattern is a [*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1 General [class.mem.general]")[.](#6.3.sentence-1)
|
||
|
||
- [(6.4)](#6.4)
|
||
|
||
In a template parameter pack that is a pack expansion ([[temp.param]](temp.param "13.2 Template parameters")):
|
||
* [(6.4.1)](#6.4.1)
|
||
|
||
if the template parameter pack is a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]");
|
||
the pattern is the [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") without the ellipsis;
|
||
|
||
* [(6.4.2)](#6.4.2)
|
||
|
||
if the template parameter pack is a [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]");
|
||
the pattern is the corresponding [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]") without the ellipsis;
|
||
|
||
* [(6.4.3)](#6.4.3)
|
||
|
||
if the template parameter pack is a template template parameter;
|
||
the pattern is the corresponding[*type-tt-parameter*](temp.param#nt:type-tt-parameter "13.2 Template parameters [temp.param]"),[*variable-tt-parameter*](temp.param#nt:variable-tt-parameter "13.2 Template parameters [temp.param]"), or[*concept-tt-parameter*](temp.param#nt:concept-tt-parameter "13.2 Template parameters [temp.param]") without the ellipsis[.](#6.4.sentence-1)
|
||
|
||
- [(6.5)](#6.5)
|
||
|
||
In an [*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") ([[dcl.init]](dcl.init "9.5 Initializers"));
|
||
the pattern is an [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")[.](#6.5.sentence-1)
|
||
|
||
- [(6.6)](#6.6)
|
||
|
||
In a [*base-specifier-list*](class.derived.general#nt:base-specifier-list "11.7.1 General [class.derived.general]") ([[class.derived]](class.derived "11.7 Derived classes"));
|
||
the pattern is a [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1 General [class.derived.general]")[.](#6.6.sentence-1)
|
||
|
||
- [(6.7)](#6.7)
|
||
|
||
In a [*mem-initializer-list*](class.base.init#nt:mem-initializer-list "11.9.3 Initializing bases and members [class.base.init]") ([[class.base.init]](class.base.init "11.9.3 Initializing bases and members")) for a[*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3 Initializing bases and members [class.base.init]") whose [*mem-initializer-id*](class.base.init#nt:mem-initializer-id "11.9.3 Initializing bases and members [class.base.init]") denotes a
|
||
base class; the pattern is the [*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3 Initializing bases and members [class.base.init]")[.](#6.7.sentence-1)
|
||
|
||
- [(6.8)](#6.8)
|
||
|
||
In a [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]") ([[temp.arg]](temp.arg "13.4 Template arguments"));
|
||
the pattern is a [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")[.](#6.8.sentence-1)
|
||
|
||
- [(6.9)](#6.9)
|
||
|
||
In an [*attribute-list*](dcl.attr.grammar#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1 Attribute syntax and semantics"));
|
||
the pattern is an [*attribute*](dcl.attr.grammar#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#6.9.sentence-1)
|
||
|
||
- [(6.10)](#6.10)
|
||
|
||
In an [*annotation-list*](dcl.attr.grammar#nt:annotation-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1 Attribute syntax and semantics"));
|
||
the pattern is an [*annotation*](dcl.attr.grammar#nt:annotation "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#6.10.sentence-1)
|
||
|
||
- [(6.11)](#6.11)
|
||
|
||
In an [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.align]](dcl.align "9.13.2 Alignment specifier")); the pattern is
|
||
the [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") without the ellipsis[.](#6.11.sentence-1)
|
||
|
||
- [(6.12)](#6.12)
|
||
|
||
In a [*capture-list*](expr.prim.lambda.capture#nt:capture-list "7.5.6.3 Captures [expr.prim.lambda.capture]") ([[expr.prim.lambda.capture]](expr.prim.lambda.capture "7.5.6.3 Captures")); the pattern is
|
||
the [*capture*](expr.prim.lambda.capture#nt:capture "7.5.6.3 Captures [expr.prim.lambda.capture]") without the ellipsis[.](#6.12.sentence-1)
|
||
|
||
- [(6.13)](#6.13)
|
||
|
||
In a [sizeof... expression](expr.sizeof "7.6.2.5 Sizeof [expr.sizeof]"); the pattern is an[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")[.](#6.13.sentence-1)
|
||
|
||
- [(6.14)](#6.14)
|
||
|
||
In a [*pack-index-expression*](expr.prim.pack.index#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]");
|
||
the pattern is an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")[.](#6.14.sentence-1)
|
||
|
||
- [(6.15)](#6.15)
|
||
|
||
In a [*pack-index-specifier*](dcl.type.pack.index#nt:pack-index-specifier "9.2.9.4 Pack indexing specifier [dcl.type.pack.index]");
|
||
the pattern is a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")[.](#6.15.sentence-1)
|
||
|
||
- [(6.16)](#6.16)
|
||
|
||
In a [*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") ([[expr.prim.fold]](expr.prim.fold "7.5.7 Fold expressions"));
|
||
the pattern is the [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") that contains an unexpanded pack[.](#6.16.sentence-1)
|
||
|
||
- [(6.17)](#6.17)
|
||
|
||
In a fold expanded constraint ([[temp.constr.fold]](temp.constr.fold "13.5.2.5 Fold expanded constraint"));
|
||
the pattern is the constraint of that fold expanded constraint[.](#6.17.sentence-1)
|
||
|
||
[*Example [5](#example-5)*: template<class ... Types> void f(Types ... rest);template<class ... Types> void g(Types ... rest) { f(&rest ...); // â&rest ...'' is a pack expansion; â&rest'' is its pattern} â *end example*]
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3244)
|
||
|
||
For the purpose of determining whether a pack satisfies a rule
|
||
regarding entities other than packs, the pack is
|
||
considered to be the entity that would result from an instantiation of
|
||
the pattern in which it appears[.](#7.sentence-1)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3250)
|
||
|
||
A pack whose name appears within the pattern of a pack
|
||
expansion is expanded by that pack expansion[.](#8.sentence-1)
|
||
|
||
An appearance of the name of
|
||
a pack is only expanded by the innermost enclosing pack expansion[.](#8.sentence-2)
|
||
|
||
The pattern of a pack expansion shall name one or more packs that
|
||
are not expanded by a nested pack expansion; such packs are called[*unexpanded packs*](#def:pack,unexpanded "13.7.4 Variadic templates [temp.variadic]") in the pattern[.](#8.sentence-3)
|
||
|
||
All of the packs expanded
|
||
by a pack expansion shall have the same number of arguments specified[.](#8.sentence-4)
|
||
|
||
An
|
||
appearance of a name of a pack that is not expanded is
|
||
ill-formed[.](#8.sentence-5)
|
||
|
||
[*Example [6](#example-6)*: template<typename...> struct Tuple {};template<typename T1, typename T2> struct Pair {};
|
||
|
||
template<class ... Args1> struct zip {template<class ... Args2> struct with {typedef Tuple<Pair<Args1, Args2> ... > type; };};
|
||
|
||
typedef zip<short, int>::with<unsigned short, unsigned>::type T1; // T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>>typedef zip<short>::with<unsigned short, unsigned>::type T2; // error: different number of arguments specified for Args1 and Args2template<class ... Args>void g(Args ... args) { // OK, Args is expanded by the function parameter pack args f(const_cast<const Args*>(&args)...); // OK, âArgs'' and âargs'' are expanded f(5 ...); // error: pattern does not contain any packs f(args); // error: pack âargs'' is not expanded f(h(args ...) + args ...); // OK, first âargs'' expanded within h,// second âargs'' expanded within f} â *end example*]
|
||
|
||
[9](#9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3287)
|
||
|
||
The instantiation of a pack expansion considers
|
||
items E1,E2,â¦,EN,
|
||
whereN is the number of elements in the pack expansion parameters[.](#9.sentence-1)
|
||
|
||
Each Ei is generated by instantiating the pattern and
|
||
replacing each pack expansion parameter with its ith element[.](#9.sentence-2)
|
||
|
||
Such an element, in the context of the instantiation, is interpreted as
|
||
follows:
|
||
|
||
- [(9.1)](#9.1)
|
||
|
||
if the pack is a template parameter pack, the element is
|
||
* [(9.1.1)](#9.1.1)
|
||
|
||
a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") for a type template parameter pack,
|
||
|
||
* [(9.1.2)](#9.1.2)
|
||
|
||
an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") for a constant template parameter pack, or
|
||
|
||
* [(9.1.3)](#9.1.3)
|
||
|
||
a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") for a template template parameter pack
|
||
|
||
designating the ith corresponding
|
||
type, constant, or template template argument;
|
||
|
||
- [(9.2)](#9.2)
|
||
|
||
if the pack is a function parameter pack, the element is an[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") designating the ith function parameter
|
||
that resulted from instantiation of
|
||
the function parameter pack declaration;
|
||
|
||
- [(9.3)](#9.3)
|
||
|
||
if the pack is an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack,
|
||
the element is an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") designating the variable introduced by
|
||
the ith [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") that resulted from instantiation of
|
||
the [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack declaration;
|
||
otherwise
|
||
|
||
- [(9.4)](#9.4)
|
||
|
||
if the pack is a structured binding pack,
|
||
the element is an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") designating the ith structured binding in the pack
|
||
that resulted from the structured binding declaration.
|
||
|
||
When N is zero, the instantiation of a pack expansion
|
||
does not alter the syntactic interpretation of the enclosing construct,
|
||
even in cases where omitting the pack expansion entirely would
|
||
otherwise be ill-formed or would result in an ambiguity in the grammar[.](#9.sentence-4)
|
||
|
||
[10](#10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3338)
|
||
|
||
The instantiation of a sizeof... expression ([[expr.sizeof]](expr.sizeof "7.6.2.5 Sizeof")) produces
|
||
an integral constant with value N[.](#10.sentence-1)
|
||
|
||
[11](#11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3342)
|
||
|
||
When instantiating a [*pack-index-expression*](expr.prim.pack.index#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") P,
|
||
let K be the index of P[.](#11.sentence-1)
|
||
|
||
The instantiation of P is the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") EK[.](#11.sentence-2)
|
||
|
||
[12](#12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3347)
|
||
|
||
When instantiating a [*pack-index-specifier*](dcl.type.pack.index#nt:pack-index-specifier "9.2.9.4 Pack indexing specifier [dcl.type.pack.index]") P,
|
||
let K be the index of P[.](#12.sentence-1)
|
||
|
||
The instantiation of P is the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") EK[.](#12.sentence-2)
|
||
|
||
[13](#13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3352)
|
||
|
||
The instantiation of an [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") with an ellipsis
|
||
produces E1 E2 … EN[.](#13.sentence-1)
|
||
|
||
[14](#14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3356)
|
||
|
||
The instantiation of a [*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") ([[expr.prim.fold]](expr.prim.fold "7.5.7 Fold expressions")) produces:
|
||
|
||
- [(14.1)](#14.1)
|
||
|
||
( ((E1*op* E2)*op* â¯)*op* EN) for a unary left fold,
|
||
|
||
- [(14.2)](#14.2)
|
||
|
||
( E1 *op*(⯠*op*(ENâ1 *op*EN))) for a unary right fold,
|
||
|
||
- [(14.3)](#14.3)
|
||
|
||
( (((E*op* E1)*op* E2)*op* â¯)*op* EN) for a binary left fold, and
|
||
|
||
- [(14.4)](#14.4)
|
||
|
||
( E1 *op*(⯠*op*(ENâ1 *op*(EN *op*E)))) for a binary right fold[.](#14.sentence-1)
|
||
|
||
In each case,*op* is the [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]")[.](#14.sentence-2)
|
||
|
||
For a binary fold,E is generated
|
||
by instantiating the [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") that did not contain an unexpanded pack[.](#14.sentence-3)
|
||
|
||
[*Example [7](#example-7)*: template<typename ...Args>bool all(Args ...args) { return (... && args); }bool b = all(true, true, true, false);
|
||
|
||
Within the instantiation of all,
|
||
the returned expression expands to((true && true) && true) && false,
|
||
which evaluates to false[.](#14.sentence-4)
|
||
|
||
â *end example*]
|
||
|
||
If N is zero for a unary fold,
|
||
the value of the expression is shown in Table [20](#tab:temp.fold.empty "Table 20: Value of folding empty sequences");
|
||
if the operator is not listed in Table [20](#tab:temp.fold.empty "Table 20: Value of folding empty sequences"),
|
||
the instantiation is ill-formed[.](#14.sentence-5)
|
||
|
||
Table [20](#tab:temp.fold.empty) — Value of folding empty sequences [[tab:temp.fold.empty]](./tab:temp.fold.empty)
|
||
|
||
| [ð](#tab:temp.fold.empty-row-1)<br>**Operator** | **Value when pack is empty** |
|
||
| --- | --- |
|
||
| [ð](#tab:temp.fold.empty-row-2)<br>&& | true |
|
||
| [ð](#tab:temp.fold.empty-row-3)<br>|| | false |
|
||
| [ð](#tab:temp.fold.empty-row-4)<br>, | void() |
|
||
|
||
[15](#15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3430)
|
||
|
||
A fold expanded constraint is not instantiated ([[temp.constr.fold]](temp.constr.fold "13.5.2.5 Fold expanded constraint"))[.](#15.sentence-1)
|
||
|
||
[16](#16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3433)
|
||
|
||
The instantiation of any other pack expansion
|
||
produces a list of elements E1,E2,â¦,EN[.](#16.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
The variety of list varies with the context:[*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]"),[*base-specifier-list*](class.derived.general#nt:base-specifier-list "11.7.1 General [class.derived.general]"),[*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]"), etc[.](#16.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
When N is zero, the instantiation of the expansion produces an empty list[.](#16.sentence-3)
|
||
|
||
[*Example [8](#example-8)*: template<class... T> struct X : T... { };template<class... T> void f(T... values) { X<T...> x(values...);}template void f<>(); // OK, X<> has no base classes// x is a variable of type X<> that is value-initialized â *end example*]
|