# Template parameters and template arguments

From cppreference.com
< cpp‎ | language

Every template is parametrized by one or more template parameters, indicated in the parameter-list of the template declaration syntax:

`template` `<` parameter-list `>` declaration | (1) |

Each parameter in parameter-list may be:

- a non-type template parameter;
- a type template parameter;
- a template template parameter.

#### Non-type template parameter

type name(optional) | (1) |
type name(optional) `=` default | (2) |
type `...` name(optional) | (3) | (since C++11)
`auto` name | (4) | (since C++17)

1) A non-type template parameter with an optional name.
2) A non-type template parameter with an optional name and a default value.
3) A non-type template parameter pack with an optional name.
4) A non-type template parameter with a deduced type (note, it may also be auto ** or any other type that includes the placeholder `auto` )

type is one of the following types (optionally cv-qualified, the qualifiers are ignored):

- std::nullptr_t (since C++11);
- integral type;
- lvalue reference type (to object or to function);
- pointer type (to object or to function);
- pointer to member type (to member object or to member function);
- enumeration type.

Array and function types may be written in a template declaration, but they are automatically replaced by pointer to object and pointer to function as appropriate.

When the name of a non-type template parameter is used in an expression within the body of the class template, it is an unmodifiable prvalue unless its type was an lvalue reference type.

A template parameter of the form class Foo is not an unnamed non-type template parameter of type `Foo`, even if otherwise class Foo is an elaborated type specifier and class Foo x; declares `x` to be of type `Foo`.

The type of a non-type template parameter may be deduced if it includes the placeholder keyword `auto`:

    template<auto n> struct B { /* ... */ };
    B<5> b1;   // OK: non-type template parameter type is int
    B<'a'> b2; // OK: non-type template parameter type is char
    B<2.5> b3; // error: non-type template parameter type cannot be double

(since C++17)

#### Type template parameter

`typename` name(optional) | (1) |
`class` name(optional) | (2) |
`typename|class` name(optional) `=` default | (3) |
`typename|class` `...` name(optional) | (4) | (since C++11)

1) A type template parameter with an optional name.
2) Exactly the same as 1).
3) A type template parameter with an optional name and a default.
4) A type template parameter pack with an optional name.

In the body of the template declaration, the name of a type parameter is a typedef-name which aliases the type supplied when the template is instantiated.

There is no difference between the keywords `class` and `typename` in a type template parameter declaration.

#### Template template parameter

`template` `<` parameter-list `>` `typename(C++17)|class` name(optional) | (1) |
`template` `<` parameter-list `>` `typename(C++17)|class` name(optional) `=` default | (2) |
`template` `<` parameter-list `>` `typename(C++17)|class` `...` name(optional) | (3) | (since C++11)

1) A template template parameter with an optional name.
2) A template template parameter with an optional name and a default.
3) A template template parameter pack with an optional name.

Unlike type template parameter declaration, template template parameter declaration can only use the keyword `class` and not `typename`. | (until C++17)

In the body of the template declaration, the name of this parameter is a template-name (and needs arguments to be instantiated).

    template<typename T> class my_array {};

    // two type template parameters and one template template parameter:
    template<typename K, typename V, template<typename> typename C = my_array>
    class Map
    {
        C<K> key;
        C<V> value;
    };

### Template arguments

In order for a template to be instantiated, every template parameter (type, non-type, or template) must be replaced by a corresponding template argument. For class templates, the arguments are either explicitly provided, deduced from the initializer, (since C++17) or defaulted. For function templates, the arguments are explicitly provided, deduced from the context, or defaulted.

If an argument can be interpreted as a both a type-id and an expression, it is always interpreted as a type-id, even if the corresponding template parameter is non-type:

    template<class T> void f(); // #1
    template<int I> void f(); // #2
    void g() {
        f<int()>(); // "int()" is both a type and an expression,
                    // calls #1 because it is interpreted as a type
    }

#### Template non-type arguments

The following limitations apply when instantiating templates that have non-type template parameters:

- For integral and arithmetic types, the template argument provided during instantiation must be a converted constant expression of the template parameter's type (so certain implicit conversion applies).
- For pointers to objects, the template arguments have to designate the address of an object with static storage duration and a linkage (either internal or external), or a constant expression that evaluates to the appropriate null pointer or std::nullptr_t value.
- For pointers to functions, the valid arguments are pointers to functions with linkage (or constant expressions that evaluate to null pointer values).
- For lvalue reference parameters, the argument provided at instantiation cannot be a temporary, an unnamed lvalue, or a named lvalue with no linkage (in other words, the argument must have linkage).
- For pointers to members, the argument has to be a pointer to member expressed as &Class::Member or a constant expression that evaluates to null pointer or std::nullptr_t value.

In particular, this implies that string literals, addresses of array elements, and addresses of non-static members cannot be used as template arguments to instantiate templates whose corresponding non-type template parameters are pointers to objects.

(until C++17)

The template argument that can be used with a non-type template parameter can be any converted constant expression of the type of the template parameter.

    template<const int* pci> struct X {};
    int ai[10];
    X<ai> xi;  // ok: array to pointer conversion and cv-qualification conversion

    struct Y {};
    template<const Y& b> struct Z {};
    Y y;
    Z<y> z;  // ok: no conversion

    template<int (&pa)[5]> struct W {};
    int b[5];
    W<b> w; // ok: no conversion

    void f(char);
    void f(int);
    template<void (*pf)(int)> struct A {};
    A<&f> a; // ok: overload resolution selects f(int)

The only exceptions are that non-type template parameters of reference and pointer type cannot refer to/be the address of

- a subobject (including non-static class member, base subobject, or array element);
- a temporary object (including one created during reference initialization);
- a string literal;
- the result of typeid;
- or the predefined variable __func__.

    template<class T, const char* p> class X {};
    X<int, "Studebaker"> x1; // error: string literal as template-argument

    template<int* p> class X {};
    int a[10];
    struct S
    {
        int m;
        static int s;
    } s;
    X<&a[2]> x3;  // error: address of array element
    X<&s.m> x4;   // error: address of non-static member
    X<&s.s> x5;   // ok: address of static member
    X<&S::s> x6;  // ok: address of static member

    template<const int& CRI> struct B {};
    B<1> b2;     // error: temporary would be required for template argument
    int c = 1;
    B<c> b1;     // ok

(since C++17)

#### Template type arguments

A template argument for a type template parameter must be a type-id, which may name an incomplete type:

    template<typename T> class X {}; // class template

    struct A; // incomplete type
    typedef struct {} B; // type alias to an unnamed type

    int main()
    {
        X<A> x1; // ok: 'A' names a type
        X<A*> x2; // ok: 'A*' names a type
        X<B> x3; // ok: 'B' names a type
    }

#### Template template arguments

A template argument for a template template parameter must be an id-expression which names a class template or a template alias.

When the argument is a class template, only the primary template is considered when matching the parameter. The partial specializations, if any, are only considered when a specialization based on this template template parameter happens to be instantiated.

    template<typename T> class A { int x; }; // primary template
    template<class T> class A<T*> { long x; }; // partial specialization

    // class template with a template template parameter V
    template<template<typename> class V> class C
    {
        V<int> y; // uses the primary template
        V<int*> z; // uses the partial specialization
    };

    C<A> c; // c.y.x has type int, c.z.x has type long

To match a template template argument `A` to a template template parameter `P`, each of the template parameters of `A` must match corresponding template parameters of `P` exactly (until C++14)`P` must be at least as specialized as `A` (since C++14). If `P`'s parameter list includes a parameter pack, zero or more template parameters (or parameter packs) from `A`'s template parameter list are matched by it.

    template<typename T> struct eval; // primary template

    template<template<typename, typename...> class TT, typename T1, typename... Rest>
    struct eval<TT<T1, Rest...>> {}; // partial specialization of eval

    template<typename T1> struct A;
    template<typename T1, typename T2> struct B;
    template<int N> struct C;
    template<typename T1, int N> struct D;
    template<typename T1, typename T2, int N = 17> struct E;

    eval<A<int>> eA; // ok: matches partial specialization of eval
    eval<B<int, float>> eB; // ok: matches partial specialization of eval
    eval<C<17>> eC; // error: C does not match TT in partial specialization because
                    // TT's first parameter is a type template parameter,
                    // while 17 does not name a type
    eval<D<int, 17>> eD; // error: D does not match TT in partial specialization
                         // because TT's second parameter is a type parameter pack,
                         // while 17 does not name a type
    eval<E<int, float>> eE; // error: E does not match TT in partial specialization
                            // because E's third (default) parameter is a non-type

    template<class T> class A { /* ... */ };
    template<class T, class U = T> class B { /* ... */ };
    template <class ...Types> class C { /* ... */ };

    template<template<class> class P> class X { /* ... */ };
    X<A> xa; // OK
    X<B> xb; // OK in C++14 after CWG 150
             // Error earlier: not an exact match
    X<C> xc; // OK in C++14 after CWG 150
             // Error earlier: not an exact match

    template<template<class ...> class Q> class Y { /* ... */ };
    Y<A> ya; // OK
    Y<B> yb; // OK
    Y<C> yc; // OK

    template<auto n> class D { /* ... */ }; // note: C++17
    template<template<int> class R> class Z { /* ... */ };
    Z<D> zd; // OK

    template <int> struct SI { /* ... */ };
    template <template <auto> class> void FA();  // note: C++17
    FA<SI>();  // Error

Formally, a template template-parameter `P` is at least as specialized as a template template argument `A` if, given the following rewrite to two function templates, the function template corresponding to `P` is at least as specialized as the function template corresponding to `A` according to the partial ordering rules for function templates. Given an invented class template `X` with the template parameter list of `A` (including default arguments):

- Each of the two function templates has the same template parameters, respectively, as `P` or `A`.
- Each function template has a single function parameter whose type is a specialization of `X` with template arguments corresponding to the template parameters from the respective function template where, for each template parameter `PP` in the template parameter list of the function template, a corresponding template argument `AA` is formed. If `PP` declares a parameter pack, then `AA` is the pack expansion `PP...`; otherwise, `AA` is the id-expression `PP`.

If the rewrite produces an invalid type, then `P` is not at least as specialized as `A`.

(since C++14)

#### Default template arguments

Default template arguments are specified in the parameter lists after the = sign. Defaults can be specified for any kind of template parameter (type, non-type, or template), but not to parameter packs.

If the default is specified for a template parameter of a primary class template , primary variable template, (since C++14)or alias template, each subsequent template parameter must have a default argument, except the very last one may be a template parameter pack. In a function template, a parameter pack may be followed by more type parameters only if they have defaults or can be deduced from the function arguments.

Default parameters are not allowed

- in the out-of-class definition of a member template (they have to be provided in the declaration inside the class body)
- in friend class template declarations

- in any function template declaration or definition

(until C++11)

On a friend function template declaration, default template arguments are allowed only if the declaration is a definition, and no other declarations of this function appear in this translation unit. | (since C++11)

Default template arguments that appear in the declarations and the definition are merged similarly to default function arguments:

    template<typename T1, typename T2 = int> class A;
    template<typename T1 = int, typename T2> class A;
    // the above is the same as the following:
    template<typename T1 = int, typename T2 = int> class A;

But the same parameter cannot be given default arguments twice in the same scope

    template<typename T = int> class X;
    template<typename T = int> class X {}; // error

The template parameter lists of template template parameters can have their own default arguments, which are only in effect where the template template parameter itself is in scope:

    // class template, with a type template parameter with a default
    template<typename T = float> struct B {};

    // template template parameter T has a parameter list, which
    // consists of one type template parameter with a default
    template<template<typename = float> typename T> struct A
    {
        void f();
        void g();
    };

    // out-of-body member function template definitions
    template<template<typename TT> class T>
    void A<T>::f()
    {
        T<> t; // error: TT has no default in scope
    }
    template<template<typename TT = char> class T>
    void A<T>::g()
    {
        T<> t; // ok: t is T<char>
    }

Member access for the names used in a default template parameter is checked at the declaration, not at the point of use:

    class B {};

    template<typename T> class C
    {
        protected:
            typedef T TT;
    };

    template<typename U, typename V = typename U::TT> class D: public U {};

    D<C<B>>* d; // error: C::TT is protected

The default template argument is implicitly instantiated when the value of that default argument is needed, except if the template is used to name a function:

    template<typename T, typename U = int> struct S { };
    S<bool>* p; // The default argument for U is instantiated at this point
                // the type of p is S<bool, int>*

(since C++14)

### Examples

#### Non-type template parameters

Run this code

    #include <iostream>

    // simple non-type template parameter
    template<int N>
    struct S { int a[N]; };

    template<const char*>
    struct S2 {};

    // complicated non-type example
    template
    <
        char c, // integral type
        int (&ra)[5], // lvalue reference to object (of array type)
        int (*pf)(int), // pointer to function
        int (S<10>::*a)[10] // pointer to member object (of type int[10])
    > struct Complicated
    {
        // calls the function selected at compile time
        // and stores the result in the array selected at compile time
        void foo(char base)
        {
            ra[4] = pf(c - base);
        }
    };

    S2<"fail"> s2; // error: string literal cannot be used
    char okay[] = "okay"; // static object with linkage
    S2< &okay[0] > s2; // error: array element has no linkage
    S2<okay> s2; // works

    int a[5];
    int f(int n) { return n; }

    int main()
    {
        S<10> s; // s.a is an array of 10 int
        s.a[9] = 4;

        Complicated<'2', a, f, &S<10>::a> c;
        c.foo('0');

        std::cout << s.a[9] << a[4] << '\n';
    }

Output:

    42

| This section is incomplete Reason: more examples

### Defect reports

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

DR | Applied to | Behavior as published | Correct behavior
--- | --- | --- | ---
CWG 150 | C++14 | template-template arguments had to match parameter lists of template-template parameters exactly | more specialized also allowed

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/language/template_parameters&oldid=91999"
Category:

- Todo with reason

Hidden category:

- Pages with unreviewed CWG DR marker