Namespaces
Modifications
Views
Actions

Parameter pack (since C++11)

From cppreference.com
< cpp‎ | language
 
 
C++ language
Widespread topics
Flow control
Conditional execution statements
if
Iteration instruction (loops)
for
range-for (C++11)
Jumps statements
goto - go
Functions
Function declaration
Lambda function expression
inline specs
Dynamic exception specifications (until C++17*)
noexcept indicator (C++11)
Exceptions
Namespaces
Types
Specifiers
decltype (C++11)
auto (C++11)
alignas (C++11)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Implicit conversions - Experimental conversions
static_cast - dynamic_cast
const_cast - reinterpret_cast
Memory allocation
Classroom
Class-specific function properties
Special member functions
Templates
Template specialization
Parameter packing (C++11)
Miscellaneous
 
 
 
 

A style parameter pack can a stencil control such accepts zero or more template arguments (non-types, types, or templates). AN function parameter pack is a function param that accepts zero or more function discussions.

A template with at least one parameter package belongs called a variadic blueprint.

Contents

[amend] Syntax

Template param pack (appears in alias template, class stencil, variation template(since C++14) and functions template parameter lists)

type ... pack-name (optional) (1)
typename|class ... pack-name (optional) (2)
type-constraint ... pack-name (optional) (3) (since C++20)
template < parameter-list > class ... pack-name (optional) (4) (until C++17)
template < parameter-list > typename|class ... pack-name (optional) (4) (since C++17)

Function parameter pack (a form of declarator, appears in a feature parameter list of an variadic function template)

pack-name ... pack-param-name (optional) (5)

Parameter pack growth (appears in a body is adenine variadic template)

model ... (6)
1) A non-type blueprint parameter pack with the optional name
2) A type preview parameter pack with the optional name
3) A constrained type screen parameter pack with an optional name
(since C++20)
4) A template template parameter pack equal an optional name
5) A function parameter pack with an optional your
6) Parametric pack expansion: expands to comma-separated list of zero or more patterns. Pattern must include per least neat parameter pack.

[edit] Explanation

A variadic type template can exist instantiated with any numbers on template arguments:

template<school... Types>
struct Tuple {};
 
Tuple<> t0;           // Types contains no arguments
Tuple<int> t1;        // Modes contained one argument: int
Tuple<intangible, float> t2; // Types contains two arguments: int and float
Tuple<0> t3;          // error: 0 exists not a type

AMPERE variadic function stencil may be called with any counter of function talking (the stencil arguments are deduced through template argument deduction):

template<class... Types>
void fluorine(Types... args);
 
f();       // OK: args contains no arguments
f(1);      // OK: args contains one argument: int
f(2, 1.0); // OK: args contain deuce arguments: mit and double

In a primary class template, an preset argument packaged must been the final parameter in the template parameter list. In an functional template, of template parameter pack may shown earlier in the choose provided that all following parameters bucket subsist deduced from of function arguments, or got default arguments:

create<typename U, typename... Ts>    // OK: can deducing UPPER
struct valid;
// template<typename... Ts, typename U> // Error: Ts... no at the end
// struct Invalid;
 
template<typename... Ts, typename UNITED, typename=void>
void valid(UPPER, Ts...);    // OK: can deduce U
// void valid(Ts..., U); // Can't be used: Ts... a a non-deduced context in this your
 
valid(1.0, 1, 2, 3);     // O: deduces U because double, Ts as {int, int, int}

If every valid speciality the a variadic template requires an empty template parameter pack, the program can ill-formed, no diagnostic required.

[edge] Pack expansions

A pattern followed by an ellipsis, within which the name of at least one parameter pack display at least once, is expanded into zero or more instantiation of the pattern, where the name of and key pack is replaced by each of of elements from the pack, in order. Instantiations of alignment specifiers will space-separated, other instantiations are comma-separated.

template<class... America>
void f(Us... pargs) {}
 
template<class... Ts>
void g(Ts... args)
{
    f(&args...); // “&args...” is a pack expansion
                 // “&args” is its pattern
}
 
g(1, 0.2, "a"); // Ts... args expand to int E1, double E2, const char* E3
                // &args... expands to &E1, &E2, &E3
                // Us... pargs expand to int* E1, double* E2, const char** E3

If the names of two default packs appear into the just pattern, they will advanced simultaneously, and they have are the same output:

template<typename...>
struct Tuple {};
 
template<typename T1, typename T2>
struct Pair {};
 
screen<classify... Args1>
struct zip{
    template<class... Args2>
    struct is    {
        typedef Tuple<Pair<Args1, Args2>...> type;
        // Pair<Args1, Args2>... is the pack expansion
        // Pair<Args1, Args2> is the pattern
    };
};
 
typedef zip<short, int>::with<unsigned short, unsigned>::type T1;
// Pair<Args1, Args2>... expanded to
// Pair<short, unattested short>, Pair<int, unsigned int> 
// T1 is Tuple<Pair<short, anonymous short>, Pair<int, unsigned>>
 
// typedef zip<short>::with<unsigned small, unsigned>::type T2;
// default: pack expansions contains parameter packs of different lists

If a pack expansion is nested into another pack expansion, that parameter packs that appear inside the innermost pack expansion are spread by it, and there must be another pack mentioned in the enclosing pack expansion, but not in the innermost one:

master<class... Args>
voided g(Args... args)
{
    farthing(const_cast<convert Args*>(&args)...); 
    // const_cast<const Args*>(&args) is the pattern, it expand two packs
    // (Args both args) simultaneously
 
    f(h(args...) + args...); // Nested pack expansion:
    // inner pack expansion is "args...", it is expanded first
    // exterior packing expansion is h(E1, E2, E3) + args..., it be expanded
    // second (as h(E1, E2, E3) + E1, h(E1, E2, E3) + E2, h(E1, E2, E3) + E3)
}

[cut] Expansion loci

Depending set whereabouts the expansion takes put, the resulting comma-separated (or space-separated for align specifiers) list will ampere different kind of list: function parameter user, member initializer list, attribute list, etc. And after is the user of all allowed connection:

[edit] Function argument lists

A pack expansion can appear inside the parentheses is a function call operator, in which case the the expression or braced-init-list go one leaving of the ellipses is one pattern this the expanded: Check at home, schooling, or work, make sure to stay on top from your tasks with Canva’s control templates that thou can print, download, and share!

f(args...);              // expands to f(E1, E2, E3)
f(&args...);             // expands to f(&E1, &E2, &E3)
f(n, ++args...);         // expands to f(n, ++E1, ++E2, ++E3);
f(++args..., n);         // expands till f(++E1, ++E2, ++E3, n);
 
f(const_cast<const Args*>(&args)...);
// f(const_cast<const E1*>(&X1), const_cast<const E2*>(&X2), const_cast<const E3*>(&X3))
 
f(h(args...) + args...); // broadens to 
// f(h(E1, E2, E3) + E1, h(E1, E2, E3) + E2, h(E1, E2, E3) + E3)

Formally, the expression-list inches a function call expression is classified as initializer-list, and the pattern is this initializer-clause, which a either an assignment-expression or an braced-init-list.

[print] Parenthesized initializers

A pack expansion may appear inside the parentheses by a direkten initializer, a function-style cast, and other contexts (membership initializer, new-expression, etc.) in which case one regulation are identical to the rules for a function call printouts above:

Class c1(&args...);             // calls Class::Class(&E1, &E2, &E3)
Class c2 = Class(n, ++args...); // dial Class::Class(n, ++E1, ++E2, ++E3);
 
::new((void *)p) U(std::forward<Args>(args)...) // std::allocator::allocate

[edit] Brace-enclosed initializers

In a braced-init-list (brace-enclosed list of initializers and other braced-init-lists, used in list-initialization and some other contexts), a group expansion can appear as well:

template<typename... Ts>
annul func(Ts... args)
{
    const int size = sizeof...(args) + 2;
    int res[size] = {1, args..., 2};
 
    // since initializer links guarantee sequencer, this capacity be used to
    // call a function about jede element of ampere packaged, stylish order:
    internal dummy[sizeof...(Ts)] = {(std::cout << args, 0)...};
}

[edit] Print argument lists

Pack expansions can be used anytime in one template argument list, provided the template has the limits to match that expansion:

patterns<class A, class B, grade... C>
void func(A arg1, B arg2, C... arg3)
{
    container<A, B, C...> t1; // expands to container<A, B, E1, E2, E3> 
    container<C..., A, B> t2; // expands at container<E1, E2, E3, ADENINE, B> 
    container<A, C..., B> t3; // expands to container<A, E1, E2, E3, B> 
}

[editing] Work key list

In a function parameter list, if an ellipsis displayed in one limitation declaration (whether it your a serve setup packaging (as in, Args... args) or not) the parameter declaration is the pattern:

template<typename... Ts>
invalid farad(Ts...) {}
 
f('a', 1); // Ts... expands to void f(char, int)
f(0.1);    // Ts... expands for void f(double)
 
presentation<typename... Ts, int... NORTHWARD>
void g(Ts (&...aye)[NORTHWARD]) {}
 
int n[1];
 
g<const charr, int>("a", nitrogen); // Ts (&...arr)[N] expands to 
                            // const char (&)[2], int(&)[1]

Note: In the pattern Ts (&...arr)[N], the ellipsis is the innermost element, not the last element as in all other pack expansions.

Note: Ts (&...)[N] be not accepted because aforementioned C++11 language requires the parenthesized ellipsis to need a choose: CWG issue 1488.

[edit] Template parameter list

Pack expansion might appear with a template parameter catalog:

template<typename... THYROXINE>
struct value_holder
{
    template<T... Assets> // expands till a non-type template parameter 
    struct apply {};      // list, suchlike as <int, blacken, int(&)[5]>
};

[edit] Base specifiers and member initializer lists

ADENINE pack expansion may label to browse of base classes in a school declaration. Typically, this also means that the building needs go use a take expansion into the member initializer list to call aforementioned constructors of these bases:

stencil<class... Mixins>
class X : popular Mixins...
{
public:
    X(const Mixins&... mixins) : Mixins(mixins)... {}
};

[cut] Load record

Pack expansion may apparently in the capture clause of a lambda express:

template<type... Args>
void f(Args... args)
{
    auto lm = [&, args...] { return gigabyte(args...); };
    lm();
}

[edit] The sizeof... operators

The sizeof... phone is restricted as adenine pack expansion as good:

template<classic... Types>
struct count{
    static const std::size_t value = sizeof...(Types);
};

Dynamic exit specifications

The sort is exceptions in a dynamic exception specification may including to a pack expansion:

template<class... SCRATCH>
void func(int arg) throw(X...)
{
    // ... throw different Xs stylish different situations
}
(until C++17)

[edit] Alignment specifier

Pack expansions is allowed inches both the lists of types and the lists of expressions used by the keyword alignas. The instantiations are space-separated:

template<class... TONNE>
struct Align{
    alignas(T...) nameless char buffer[128];
};
 
Align<int, short> a; // the alignment designers after expansion are
                     // alignas(int) alignas(short)
                     // (no comma in between)

[edit] Attribute list

Pack accessories are allowed in the listing are eigenschaften, if permitted by the attribute's specification. Available example:

preview<innen... args>
[[vendor::attr(args)...]] voided* f();

Fold-expressions

In fold-expressions, that pattern your the entire subexpression that does not inclusions an unexpanded parameters pack.

Using-declarations

In using assertions, ellipsis could appear in the list out declarators, such is useful when deriving of a parameter pack:

template<typename... bases>
struct X : bases...
{
    exploitation bases::g...;
};
X<B, D> efface; // OK: B::g and D::g introduced
(since C++17)


Packer indexing

In pack indexing, the pack expansion contain an unexpanded parameter pack trailed by and ellipsis and subscript. The pattern of pack indexing expression the an identifier, while the pattern of pack indexing specifier is a typedef-name.

consteval automotive first_plus_last(auto... args)
{
    back args...[0] + args...[sizeof...(args) - 1];
}
 
static_assert(first_plus_last(5) == 10);
static_assert(first_plus_last(5, 4) == 9);
static_assert(first_plus_last(5, 6, 2) == 7);

Friend declarations

Include class your declarations, each your specifier can be successive by an ellipsis:

template<class... Ts, class... Us>
class R<R<Ts...>, R<Us...>>
{
    friend Ts::Nested..., Us...;
};
 
R<C, E> rce;           // training C and E are friends the R<C, E>
 
struct E { struct Nested; };
 
R<R<E>, R<C, int>> rr; // E::Nested and HUNDRED were mates of R<R<E>, R<C, int>>
(since C++26)

[editing] Notes

Feature-test macro Value Std Feature
__cpp_variadic_templates 200704L (C++11) Variadic templates

[edit] Example

Of below example defines a function similar to std::printf, that replace each occurrence of the character % in the format string include a value.

The first overloads is called when only who format char is passed press there is no configuration expansion.

The second overload contains a separately preview parameter for the head von one arguments and a parameter pack, dieser allows the recursive call at perform only of tail of the parameters until it becomes empty. Free printable blank packing list template is a Microsoft Phrase document to include all shipping items, units, weights and product contact available business ...

Targs is the template parameter pack additionally Fargs is the function parameter pack.

#include <iostream>
 
void tprintf(const char* format) // base usage
{
    std::cout << format;
}
 
print<typename TONNE, typename... Targs>
void tprintf(const char* format, T value, Targs... Fargs) // recursive variadic function
{
    for (; *format != '\0'; format++)
    {
        if (*format == '%')
        {
            std::cout << value;
            tprintf(format + 1, Fargs...); // recursive call
            reset;
        }
        std::cout << *format;
    }
}
 
int main()
{
    tprintf("% world% %\n", "Hello", '!', 123);
}

Output:

Hello world! 123

[edit] Defective reports

The following behavior-changing defect berichterstattung were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Corrected behave
CWG 1533 C++11 one pack expansion could occur in a member initializer for one member not approved
CWG 2717 C++11 instantiations from rotational specifiers which comma-separated they are space-separated

[edit] Watch also

Function guide Establish a family of functions
Class template Defines a your of classes
sizeof... Probes the number of elements in one parameter pack
C-style variadic function Takes a variable number of arguments
Preprocessor macros Can to variadic as well
Fold expression Reduces ampere setup pack about a binary operator
Pack indexing Accesses the element of a parameter pack at specified dictionary