Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Template (C++)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Technical overview == There are three kinds of templates: ''function templates'', ''class templates'' and, since [[C++14]], ''variable templates''. Since [[C++11]], templates may be either [[Variadic template|variadic]] or non-variadic; in earlier versions of C++ they are always non-variadic. C++ Templates are [[Turing Complete|Turing complete]].<ref>https://web.archive.org/web/20131101122512/http://ubietylab.net/ubigraph/content/Papers/pdf/CppTuring.pdf</ref> === Function templates === A ''function template'' behaves like a function except that the template can have arguments of many different types (see example). In other words, a function template represents a family of functions. The format for declaring function templates with type parameters is: <syntaxhighlight lang="cpp"> template<class identifier> declaration; template<typename identifier> declaration; </syntaxhighlight> Both expressions have the same meaning and behave in exactly the same way. The latter form was introduced to avoid confusion,<ref>{{cite web |last=Lippman |first=Stan |date=11 August 2004 |website=Microsoft Developers Network (MSDN) |url=https://docs.microsoft.com/en-us/archive/blogs/slippman/why-c-supports-both-class-and-typename-for-type-parameters |title=Why C++ Supports both Class and Typename for Type Parameters}}</ref> since a type parameter need not be a class until C++20. (It can be a basic type such as <code>int</code> or <code>double</code>.) For example, the C++ Standard Library contains the function template <code>max(x, y)</code> which returns the larger of <code>x</code> and <code>y</code>. That function template could be defined like this: <syntaxhighlight lang="cpp"> template<typename T> const T& max(const T& a, const T& b) { return a < b ? b : a; } </syntaxhighlight> This single function definition works with many data types. Specifically, it works with all data types for which '''<''' (the less-than operator) is defined and returns a value with a type convertible to <code>bool</code>. The usage of a function template saves space in the source code file in addition to limiting changes to one function description and making the code easier to read. An instantiated function template usually produces the same object code, though, compared to writing separate functions for all the different data types used in a specific program. For example, if a program uses both an <code>int</code> and a <code>double</code> version of the <code>max()</code> function template above, the [[compiler]] will create an object code version of <code>max()</code> that operates on <code>int</code> arguments and another object code version that operates on <code>double</code> arguments.{{Cn|date=September 2024}} The compiler output will be identical to what would have been produced if the source code had contained two separate non-templated versions of <code>max()</code>, one written to handle <code>int</code> and one written to handle <code>double</code>. Here is how the function template could be used: <syntaxhighlight lang="cpp"> #include <iostream> int main() { // This will call max<int> by implicit argument deduction. std::cout << std::max(3, 7) << '\n'; // This will call max<double> by implicit argument deduction. std::cout << std::max(3.0, 7.0) << '\n'; // We need to explicitly specify the type of the arguments; // although std::type_identity could solve this problem... std::cout << max<double>(3, 7.0) << '\n'; } </syntaxhighlight> In the first two cases, the template argument <code>T</code> is automatically deduced by the compiler to be <code>int</code> and <code>double</code>, respectively. In the third case automatic deduction of <code>max(3, 7.0)</code> would fail because the type of the parameters must in general match the template arguments exactly. Therefore, we explicitly instantiate the <code>double</code> version with <code>max<double>()</code>. This function template can be instantiated with any [[copy constructor|copy-constructible]] type for which the expression <code>y < x</code> is valid. For user-defined types, this implies that the less-than operator (<code><</code>) must be [[operator overloading|overloaded]] in the type. ==== Abbreviated function templates ==== Since [[C++20]], using <code>auto</code> or <code>[[concepts (C++)|Concept]] auto</code> in any of the parameters of a [[function declaration]], that declaration becomes an ''abbreviated function template'' declaration.<ref>{{cite web|url=http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1141r1.html|title=P1141R1 - Yet another approach for constrained declarations|access-date=2018-11-11|archive-date=2018-11-11|archive-url=https://web.archive.org/web/20181111133625/http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1141r1.html|url-status=live}}</ref> Such a declaration declares a function template and one invented template parameter for each placeholder is appended to the template parameter list: <syntaxhighlight lang="cpp"> void f1(auto); // same as template<class T> void f1(T) void f2(C1 auto); // same as template<C1 T> void f2(T), if C1 is a concept void f3(C2 auto...); // same as template<C2... Ts> void f3(Ts...), if C2 is a concept void f4(C2 auto, ...); // same as template<C2 T> void f4(T...), if C2 is a concept void f5(const C3 auto*, C4 auto&); // same as template<C3 T, C4 U> void f5(const T*, U&); </syntaxhighlight> === Class templates === A class template provides a specification for generating classes based on parameters. Class templates are generally used to implement [[container (data structure)|containers]]. A class template is instantiated by passing a given set of types to it as template arguments.<ref name="cpptemplates">{{cite book |last1=Vandevoorde |first1=Daveed |last2=Josuttis |first2=Nicolai |title=C++ Templates: The Complete Guide |publisher=[[Addison Wesley]] |year=2002 |isbn=978-0-201-73484-3 }}</ref> The C++ Standard Library contains many class templates, in particular the containers adapted from the [[Standard Template Library]], such as <code>[[Vector (C++)|vector]]</code>. === Variable templates === {{Main|C++14#Variable templates}} In C++14, templates can be also used for variables, as in the following example: <syntaxhighlight lang="cpp"> template<typename T> constexpr T pi = T{3.141592653589793238462643383L}; // (Almost) from std::numbers::pi </syntaxhighlight> === Non-type template parameters === Although templating on types, as in the examples above, is the most common form of templating in C++, it is also possible to template on values. Thus, for example, a class declared with <syntaxhighlight lang="cpp"> template <int K> class MyClass; </syntaxhighlight> can be instantiated with a specific <code>int</code>. As a real-world example, the [[C++ standard library|standard library]] fixed-size [[Array data type|array]] type <code>[[std::array]]</code> is templated on both a type (representing the type of object that the array holds) and a number which is of type <code>[[size_t|std::size_t]]</code> (representing the number of elements the array holds). <code>std::array</code> can be declared as follows: <syntaxhighlight lang="cpp"> template<class T, size_t N> struct array; </syntaxhighlight> and an array of six <code>char</code>s might be declared: <syntaxhighlight lang="cpp"> array<char, 6> myArray; </syntaxhighlight> === Template specialization === When a function or class is instantiated from a template, a [[template specialization|specialization]] of that template is created by the compiler for the set of arguments used, and the specialization is referred to as being a generated specialization. === Explicit template specialization === Sometimes, the programmer may decide to implement a special version of a function (or class) for a given set of template type arguments which is called an explicit specialization. In this way certain template types can have a specialized implementation that is optimized for the type or a more meaningful implementation than the generic implementation. * If a class template is specialized by a subset of its parameters it is called [[partial template specialization]] (function templates cannot be partially specialized). * If all of the parameters are specialized it is a ''full specialization''. Explicit specialization is used when the behavior of a function or class for particular choices of the template parameters must deviate from the generic behavior: that is, from the code generated by the main template, or templates. For example, the template definition below defines a specific implementation of <code>max()</code> for arguments of type <code>const char*</code>: <syntaxhighlight lang="cpp"> #include <cstring> template<> const char* max(const char* a, const char* b) { // Normally, the result of a direct comparison // between two C strings is undefined behaviour; // using std::strcmp makes defined. return std::strcmp(a, b) > 0 ? a : b; } </syntaxhighlight> === Variadic templates === C++11 introduced [[variadic template]]s, which can take a variable number of arguments in a manner somewhat similar to [[variadic function]]s such as <code>std::printf</code>. === Template aliases === C++11 introduced template aliases, which act like parameterized [[typedef]]s. The following code shows the definition of a template alias <code>StrMap</code>. This allows, for example, <code>StrMap<int></code> to be used as shorthand for <code>std::unordered_map<int,std::string></code>. <syntaxhighlight lang="cpp"> template<typename T> using StrMap = std::unordered_map<T, std::string>; </syntaxhighlight>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)