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)
- a family of variables (variable template)
- a concept (constraints and concepts)
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 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 and function templates, partial specializations are only allowed for class templates and variable templates .
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
Section titled “Syntax”template <parameter-list> requires-clause(optional) declarationexport template <parameter-list> requires-clause(optional) declarationtemplate <parameter-list> concept concept-name = constraint-expression;parameter-lista 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 .
requires-clausedeclarationdeclaration 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 , or an alias template . It may also define a template specialization.
concept-name constraint-expressionsee constraints and concepts
This section is incomplete.
Reason: core syntax, template parameters, and instantiations, take content common between class_template and function_template
Template identifiers
Section titled “Template identifiers”A template identifier has one of the following syntaxes:
template-name<template-argument-list(optional)>A simple template identifier.
operator op<template-argument-list(optional)>An operator function template identifier.
operator "" identifier<template-argument-list(optional)>operator user-defined-string-literal<template-argument-list(optional)>A literal operator function template identifier.
template-namean identifier that names a template
opan overloadable operator
identifieran 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
-
There is an argument for each non-deducible non-pack 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
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 argumentsusing T2 = X<>; // error: no default argument for first template parameterusing T3 = X<1>; // error: value 1 does not match type-parameterusing T4 = X<int>; // error: substitution failure for second template parameterusing T5 = 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<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 satisfiedPtr<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 satisfiedtemplate<> struct S<char[2]> {}; // error: constraints not satisfiedIf 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, class, or function.
Templated entity
Section titled “Templated entity”A templated entity (or, in some sources, “temploid”) is any entity that is defined (or, for a lambda expression, created) within a template definition. All of the following are templated entities:
-
a class/function /variable template
- a concept
-
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
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.Keywords
Section titled “Keywords”template, export
Defect reports
Section titled “Defect reports”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 |
See also
Section titled “See also”C documentation for Generic selection