Template (programming)
Encyclopedia
Templates are a feature of the C++
programming language that allow functions and classes to operate with generic types
. This allows a function or class to work on many different data types without being rewritten for each one.
Templates are of great utility to programmers in C++, especially when combined with multiple inheritance
and operator overloading
. The C++ Standard Library
provides many useful functions within a framework of connected templates.
This single function definition works with different kinds of data types. A function template does not occupy space in memory. The actual definitions of a function template are generated at compile-time, when the compiler has determined what types the function will be called for. The function template does not save memory.
In the first two cases, the template argument T is automatically deduced by the compiler to be
type for which the expression (y < x) is valid. For user-defined types, this implies that the less-than operator must be overloaded
.
s. A class template is instantiated by passing a given set of types to it as template arguments. The C++ Standard Library
contains many class templates, in particular the containers adapted from the Standard Template Library
, such as
. If all of the parameters are specialized it is a full specialization. Function templates cannot be partially specialized.
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.
macros. For example, the following is a C++
Both macros and templates are expanded at compile-time. Macros are always expanded inline, whereas templates are only expanded inline when the compiler deems it appropriate. When expanded inline, macro functions and template functions have no extraneous run-time overhead. Template functions with many lines of code will incur run-time overhead when they are not expanded inline, but the reduction in code size may help the code to load from disk more quickly and/or fit within RAM caches.
Templates are considered "type-safe
", that is, they require type-checking at compile-time. Hence, the compiler can determine at compile-time whether or not the type associated with a template definition can perform all of the functions required by that template definition.
By design, templates can be utilized in very complex problem spaces, whereas macros are substantially more limited.
There are fundamental drawbacks to the use of templates:
Additionally, the use of the "less-than" and "greater-than" signs as delimiters is problematic for tools (such as text editors) which analyse source code syntactically. It is difficult, or maybe impossible, for such tools to determine whether a use of these tokens is as comparison operators or template delimiters. For example, this line of code:
may be a function call with two parameters, each the result of a comparison expression. Alternatively, it could be a declaration of a constructor for class
and C# 1.0. Java's adoption of generics
mimics the behaviour of templates, but is technically different. C# added generics (parameterized types) in .NET 2.0. The generics in Ada
predate C++ templates.
Although C++ templates, Java generics, and .NET
generics are often considered similar, generics only mimic the basic behavior of C++ templates. Some of the advanced template features utilized by libraries such as Boost and STLSoft
, and implementations of the STL
itself, for template metaprogramming
(explicit or partial specialization, default template arguments, template non-type arguments, template template arguments, ...) are not available with generics.
The D programming language attempts to build on C++ redesigning a better template system. A significant addition is the inclusion of the
Also note that the
Other significant features include typesafe variadic template
functions.
This function will work for any number of arguments, with the
D templates allow a simple form of Constraints too. They can be expressed as an arbitrarily complex predicate that must evaluate at compile time. If it's true the template is a match for the arguments, otherwise the template is ignored during overload matching.
Something similar can be done in C++ with Boost enable_if.
In C++ templates, the compile-time cases are performed by pattern matching over the template arguments, so the Factorial template's base cases are implemented by matching 0 and 1 rather than with an inequality test, which is unavailable:
With these definitions, one can compute, say 6! at compile time using the expression
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
programming language that allow functions and classes to operate with generic types
Generic programming
In a broad definition, generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters...
. This allows a function or class to work on many different data types without being rewritten for each one.
Templates are of great utility to programmers in C++, especially when combined with multiple inheritance
Multiple inheritance
Multiple inheritance is a feature of some object-oriented computer programming languages in which a class can inherit behaviors and features from more than one superclass....
and operator overloading
Operator overloading
In object oriented computer programming, operator overloading—less commonly known as operator ad-hoc polymorphism—is a specific case of polymorphism, where different operators have different implementations depending on their arguments...
. The C++ Standard Library
C++ standard library
In C++, the C++ Standard Library is a collection of classes and functions, which are written in the core language and part of the C++ ISO Standard itself...
provides many useful functions within a framework of connected templates.
Technical overview
There are two kinds of templates: function templates and class templates.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. For example, the C++ Standard Library contains the function templatemax(x, y)
which returns either x or y, whichever is larger. max
could be defined like this, using the following template:This single function definition works with different kinds of data types. A function template does not occupy space in memory. The actual definitions of a function template are generated at compile-time, when the compiler has determined what types the function will be called for. The function template does not save memory.
In the first two cases, the template argument T is automatically deduced by the compiler to be
int
and double
, respectively. In the third case deduction fails because the type of the parameters must in general match the template arguments exactly. This function template can be instantiated with any copy-constructibleCopy constructor
A copy constructor is a special constructor in the C++ programming language creating a new object as a copy of an existing object. The first argument of such a constructor is a reference to an object of the same type as is being constructed , which might be followed by parameters of any type...
type for which the expression (y < x) is valid. For user-defined types, this implies that the less-than operator must be overloaded
Operator overloading
In object oriented computer programming, operator overloading—less commonly known as operator ad-hoc polymorphism—is a specific case of polymorphism, where different operators have different implementations depending on their arguments...
.
Class templates
A class template provides a specification for generating classes based on parameters. Class templates are commonly used to implement containerContainer (data structure)
In computer science, a container is a class, a data structure, or an abstract data type whose instances are collections of other objects. In other words; they are used for storing objects in an organized way following specific access rules...
s. A class template is instantiated by passing a given set of types to it as template arguments. The C++ Standard Library
C++ standard library
In C++, the C++ Standard Library is a collection of classes and functions, which are written in the core language and part of the C++ ISO Standard itself...
contains many class templates, in particular the containers adapted from the Standard Template Library
Standard Template Library
The Standard Template Library is a C++ software library which later evolved into the C++ Standard Library. It provides four components called algorithms, containers, functors, and iterators. More specifically, the C++ Standard Library is based on the STL published by SGI. Both include some...
, such as
vector
.Explicit template specialization
When a function or class is instantiated from a template, a 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). However, the programmer may decide to implement a special version of a function (or class) for a given set of template arguments which is called an explicit specialization. If a class template is specialized by a subset of its parameters it is called partial template specializationPartial template specialization
Partial template specialization is a particular form of class template specialization. Usually used in reference to the C++ programming language, it allows the programmer to specialize only some arguments of a class template, as opposed to explicit specialization, where all the template arguments...
. If all of the parameters are specialized it is a full specialization. Function templates cannot be partially specialized.
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.
Advantages and disadvantages
Some uses of templates, such as themaximum
function, were previously fulfilled by function-like preprocessorPreprocessor
In computer science, a preprocessor is a program that processes its input data to produce output that is used as input to another program. The output is said to be a preprocessed form of the input data, which is often used by some subsequent programs like compilers...
macros. For example, the following is a C++
maximum
macro:Both macros and templates are expanded at compile-time. Macros are always expanded inline, whereas templates are only expanded inline when the compiler deems it appropriate. When expanded inline, macro functions and template functions have no extraneous run-time overhead. Template functions with many lines of code will incur run-time overhead when they are not expanded inline, but the reduction in code size may help the code to load from disk more quickly and/or fit within RAM caches.
Templates are considered "type-safe
Type safety
In computer science, type safety is the extent to which a programming language discourages or prevents type errors. A type error is erroneous or undesirable program behaviour caused by a discrepancy between differing data types...
", that is, they require type-checking at compile-time. Hence, the compiler can determine at compile-time whether or not the type associated with a template definition can perform all of the functions required by that template definition.
By design, templates can be utilized in very complex problem spaces, whereas macros are substantially more limited.
There are fundamental drawbacks to the use of templates:
- Historically, some compilers exhibited poor support for templates. So, the use of templates could decrease code portability.
- Many compilers lack clear instructions when they detect a template definition error. This can increase the effort of developing templates, and has prompted the development of ConceptsConcepts (C++)Concepts and the related notion of axioms were an extension to C++'s template system proposed for C++0x. They were designed to improve compiler diagnostics and to allow programmers to codify in the program some formal properties of templates that they write...
for possible inclusion in a future C++ standard. - Since the compiler generates additional code for each template type, indiscriminate use of templates can lead to code bloatCode bloatCode bloat is the production of code that is perceived as unnecessarily long, slow, or otherwise wasteful of resources. Code bloat can be caused by inadequacies in the language in which the code is written, inadequacies in the compiler used to compile the code, or by a programmer...
, resulting in larger executables. - Because a template by its nature exposes its implementation, injudicious use in large systems can lead to longer build times.
- It can be difficult to debug code that is developed using templates. Since the compiler replaces the templates, it becomes difficult for the debugger to locate the code at runtime.
- Templates of Templates (nesting) are not supported by all compilers, or might have a max nesting level.
- Templates are in the headers, which require a complete rebuild of all project pieces when changes are made.
- No information hiding. All code is exposed in the header file. No one library can solely contain the code.
Additionally, the use of the "less-than" and "greater-than" signs as delimiters is problematic for tools (such as text editors) which analyse source code syntactically. It is difficult, or maybe impossible, for such tools to determine whether a use of these tokens is as comparison operators or template delimiters. For example, this line of code:
may be a function call with two parameters, each the result of a comparison expression. Alternatively, it could be a declaration of a constructor for class
foo
taking one parameter, "d
", whose type is the parametrised "a < b, c >
".Generic programming features in other languages
Initially, the concept of templates was not included in some languages, such as JavaJava (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
and C# 1.0. Java's adoption of generics
Generics in Java
Generics are a facility of generic programming that was added to the Java programming language in 2004 as part of J2SE 5.0. They allow "a type or method to operate on objects of various types while providing compile-time type safety." A common use of this feature is when using a Java Collection...
mimics the behaviour of templates, but is technically different. C# added generics (parameterized types) in .NET 2.0. The generics in Ada
Ada (programming language)
Ada is a structured, statically typed, imperative, wide-spectrum, and object-oriented high-level computer programming language, extended from Pascal and other languages...
predate C++ templates.
Although C++ templates, Java generics, and .NET
.NET Framework
The .NET Framework is a software framework that runs primarily on Microsoft Windows. It includes a large library and supports several programming languages which allows language interoperability...
generics are often considered similar, generics only mimic the basic behavior of C++ templates. Some of the advanced template features utilized by libraries such as Boost and STLSoft
STLSoft C++ Libraries
The STLSoft C++ Libraries are a collection of open source C++ template libraries that extend the functionality of the Standard Template Library and provide facades that wrap operating-system and technology-specific APIs. STLSoft is licensed under a BSD-form license which allows it to be used with...
, and implementations of the STL
Standard Template Library
The Standard Template Library is a C++ software library which later evolved into the C++ Standard Library. It provides four components called algorithms, containers, functors, and iterators. More specifically, the C++ Standard Library is based on the STL published by SGI. Both include some...
itself, for template metaprogramming
Template metaprogramming
Template metaprogramming is a metaprogramming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled. The output of these templates include compile-time constants, data structures, and...
(explicit or partial specialization, default template arguments, template non-type arguments, template template arguments, ...) are not available with generics.
The D programming language attempts to build on C++ redesigning a better template system. A significant addition is the inclusion of the
static if
statement, which allows conditional compilation of code based on any information known at compile time. For example:Also note that the
!
delimiters are used rather than the <>
delimiters. This prevents ambiguity in the parsing of templates.Other significant features include typesafe variadic template
Variadic Templates
In computer programming, variadic templates are templates that take a variable number of arguments.Variadic templates are supported by the D programming language, and the newest version of C++, formalized in the C++11 standard.-C++11:...
functions.
This function will work for any number of arguments, with the
foreach
iteration over the tuple of arguments expanded at compile time.D templates allow a simple form of Constraints too. They can be expressed as an arbitrarily complex predicate that must evaluate at compile time. If it's true the template is a match for the arguments, otherwise the template is ignored during overload matching.
Something similar can be done in C++ with Boost enable_if.
In C++ templates, the compile-time cases are performed by pattern matching over the template arguments, so the Factorial template's base cases are implemented by matching 0 and 1 rather than with an inequality test, which is unavailable:
With these definitions, one can compute, say 6! at compile time using the expression
Factorial<6>::value
.