Skip to content

Templates

A template is a C++ entity that defines one of the following:

  • a family of classes (class template), which may be nested classes

  • a family of functions (function template), which may be member functions

  • an alias to a family of types (alias template) (since C++11)
  • a family of variables (variable template) (since C++14)
  • a concept (constraints and concepts) (since C++20)

Templates are parameterized by one or more template parameters, of three kinds: type template parameters, constant template parameters, and template template parameters.

When template arguments are provided, or, for function and class (since C++17) templates only, deduced, they are substituted for the template parameters to obtain a specialization of the template, that is, a specific type or a specific function lvalue.

Specializations may also be provided explicitly: full specializations are allowed for class , variable (since C++14) and function templates, partial specializations are only allowed for class templates and variable templates (since C++14) .

When a class template specialization is referenced in context that requires a complete object type, or when a function template specialization is referenced in context that requires a function definition to exist, the template is instantiated (the code for it is actually compiled), unless the template was already explicitly specialized or explicitly instantiated. Instantiation of a class template does not instantiate any of its member functions unless they are also used. At link time, identical instantiations generated by different translation units are merged.

The definition of a class template must be visible at the point of implicit instantiation, which is why template libraries typically provide all template definitions in the headers (e.g., most boost libraries are header-only).

Declaration #1
template <parameter-list> requires-clause(optional) declaration
Declaration #2
export template <parameter-list> requires-clause(optional) declaration
(until C++11)
Declaration #3
template <parameter-list> concept concept-name = constraint-expression;
(until C++20)
parameter-list
-

a non-empty comma-separated list of the template parameters, each of which is either constant parameter, a type parameter, a template parameter , or a parameter pack of any of those (since C++11) .

requires-clause
-
a requires-clause that specifies the constraints on the template arguments. (since C++20)
declaration
-

declaration of a class (including struct and union), a member class or member enumeration type, a function or member function, a static data member at namespace scope , a variable or static data member at class scope (since C++14) , or an alias template (since C++11) . It may also define a template specialization.

concept-name constraint-expression
-

see constraints and concepts

export was an optional modifier which declared the template as exported (when used with a class template, it declared all of its members exported as well). Files that instantiated exported templates did not need to include their definitions: the declaration was sufficient. Implementations of export were rare and disagreed with each other on details.
(until C++11)

This section is incomplete.
Reason: core syntax, template parameters, and instantiations, take content common between class_template and function_template

A template identifier has one of the following syntaxes:

Declaration #1
template-name<template-argument-list(optional)>

A simple template identifier.

Declaration #2
operator op<template-argument-list(optional)>

An operator function template identifier.

Declaration #3
operator "" identifier<template-argument-list(optional)>
operator user-defined-string-literal<template-argument-list(optional)>

A literal operator function template identifier. (since C++11) (deprecated in C++23)

template-name
-

an identifier that names a template

op
-

an overloadable operator

identifier
-

an identifier

user-defined-string-literal
-

"" followed by an identifier

A simple template identifier that names a class template specialization names a class.

A template identifier that names an alias template specialization names a type.

A template identifier that names a function template specialization names a function.

If all following conditions are satisfied, a template identifier is valid:

  • There are at most as many arguments as there are parameters or a parameter is a template parameter pack (since C++11)

  • There is an argument for each non-deducible non-pack (since C++11) parameter that does not have a default template argument

  • Each template argument matches the corresponding template parameter

  • Substitution of each template argument into the following template parameters (if any) succeeds

  • If the template identifier is non-dependent, the associated constraints are satisfied as specified below (since C++20)

An invalid simple template id is a compile-time error, unless it names a function template specialization (in which case SFINAE may apply).

template<class T, T::type n = 0>
class X;
struct S
{
using type = int;
};
using T1 = X<S, int, int>; // error: too many arguments
using T2 = X<>; // error: no default argument for first template parameter
using T3 = X<1>; // error: value 1 does not match type-parameter
using T4 = X<int>; // error: substitution failure for second template parameter
using T5 = X<S>; // OK

When the template-name of a simple template id names a constrained non-function template or a constrained template template parameter, but not a member template that is a member of an unknown specialization, and all template arguments in the simple template id are non-dependent, the associated constraints of the constrained template must be satisfied:

template<typename T>
concept C1 = sizeof(T) != sizeof(int);
template<C1 T>
struct S1 {};
template<C1 T>
using Ptr = T*;
S1<int>* p; // error: constraints not satisfied
Ptr<int> p; // error: constraints not satisfied
template<typename T>
struct S2 { Ptr<int> x; }; // error, no diagnostic required
template<typename T>
struct S3 { Ptr<T> x; }; // OK, satisfaction is not required
S3<int> x; // error: constraints not satisfied
template<template<C1 T> class X>
struct S4
{
X<int> x; // error, no diagnostic required
};
template<typename T>
concept C2 = sizeof(T) == 1;
template<C2 T> struct S {};
template struct S<char[2]>; // error: constraints not satisfied
template<> struct S<char[2]> {}; // error: constraints not satisfied
(since C++20)

If all following conditions are satisfied, two template identifiers are same:

  • Their template-names or operators refer to the same template
  • Their corresponding type template arguments are the same type
  • The template parameter values determined by their corresponding constant template arguments are template-argument-equivalent
  • Their corresponding template template arguments refer to the same template

Two template identifier that are the same refer to the same variable, (since C++14) class, or function.

A templated entity (or, in some sources, “temploid”) is any entity that is defined (or, for a lambda expression, created) (since C++11) within a template definition. All of the following are templated entities:

  • a class/function /variable (since C++14) template

  • a concept (since C++20)
  • a member of a templated entity (such as a non-template member function of a class template)

  • an enumerator of an enumeration that is a templated entity

  • any entity defined or created within a templated entity: a local class, a local variable, a friend function, etc

  • the closure type of a lambda expression that appears in the declaration of a templated entity (since C++11)

For example, in

template<typename T>
struct A
{
void f() {}
};

the function A::f is not a function template, but is still considered to be templated.

A templated function is a function template or a function that is templated.

A templated class is a class template or a class that is templated.

A templated variable is a variable template or a variable that is templated. (since C++14)

template, export

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

CWG 2293 (C++98)
Link https://cplusplus.github.io/CWG/issues/2293.html
Applied to C++98
Behavior as published

the rules of determining whether a template identifier is valid were not provided

Correct behavior

provided

CWG 2682 (C++98)
Link https://cplusplus.github.io/CWG/issues/2682.html
Applied to C++98
Behavior as published

the definitions of templated function/template class (C++98)/templated variable (C++14) were missing

Correct behavior

added

CWG 2308 (C++98)
Link https://cplusplus.github.io/CWG/issues/2308.html
Applied to C++98
Behavior as published

two template identifiers were different if their corresponding constant template arguments are not template-argument-equivalent

Correct behavior

they are different if their corresponding constant template parameter values are not template-argument-equivalent

C documentation for Generic selection