Templates - cppreference.com

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

Templates are parameterized by one or more

template parameters

, of three kinds: type template parameters, non-type 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

).

Syntax

template <parameter-list>requires-clause(optional)declaration(1) export template <parameter-list>declaration(2) (until C++11)template <parameter-list> conceptconcept-name=constraint-expression;(3) (since C++20)parameter-list- a non-empty comma-separated list of the

template parameters

, each of which is either

non-type parameter

, a

type parameter

, a

template parameter

, or a

parameter pack

of any of those(since C++11). requires-clause- (since C++20) a

requires-clause

that specifies the

constraints

on the template arguments. 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)Template identifiers

A template identifier has one of the following syntaxes:

template-name<template-argument-list(optional)>(1) operatorop<template-argument-list(optional)>(2) operator ""identifier<template-argument-list(optional)>(3) (since C++11)
(deprecated)operatoruser-defined-string-literal<template-argument-list(optional)>(4) (since C++11)1) A simple template identifier.

2) An operator function template identifier.

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<classT,T::typen=0>classX;structS{usingtype=int;};usingT1=X<S,int,int>;// error: too many argumentsusingT2=X<>;// error: no default argument for first template parameterusingT3=X<1>;// error: value 1 does not match type-parameterusingT4=X<int>;// error: substitution failure for second template parameterusingT5=X<S>;// OKWhen 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<typenameT>conceptC1=sizeof(T)!=sizeof(int);template<C1T>structS1{};template<C1T>usingPtr=T*;S1<int>*p;// error: constraints not satisfiedPtr<int>p;// error: constraints not satisfiedtemplate<typenameT>structS2{Ptr<int>x;};// error, no diagnostic requiredtemplate<typenameT>structS3{Ptr<T>x;};// OK, satisfaction is not requiredS3<int>x;// error: constraints not satisfiedtemplate<template<C1T>classX>structS4{X<int>x;// error, no diagnostic required};template<typenameT>conceptC2=sizeof(T)==1;template<C2T>structS{};templatestructS<char[2]>;// error: constraints not satisfiedtemplate<>structS<char[2]>{};// error: constraints not satisfied(since C++20)If all following conditions are satisfied, two template identifiers are same :

Their template-name s or operators refer to the same template.

Their corresponding type template arguments are the same type.

The template parameter values determined by their corresponding non-type 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.

Templated entity

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 template

an entity defined or created within the item-declaration or compound-statement of an

expansion statement

(since C++26)an entity defined or created within a templated entity (such as a local class, a local or block variable, or a friend function)

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

the closure type of a lambda expression that appears in the declaration of a templated entity

(since C++11)For example, in

template<typenameT>structA{voidf(){}};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)Keywords

template

,

export

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 2293

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

CWG 2682

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

P2308R1

C++98 two template identifiers were different if their
corresponding non-type template arguments
are not template-argument-equivalent they are different if their corresponding
non-type template parameter values
are not template-argument-equivalent See also