Template (programming)
From Wikipedia, the free encyclopedia
In computer programming, templates are a feature of the C++ programming language that allow code to be written without consideration of the data type with which it will eventually be used. Templates support generic programming in C++.
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.
Contents |
[edit] Technical overview
There are two kinds of templates: function templates and class templates.
[edit] Function templates
A function template behaves like a function that can accept arguments of many different types. For example, the C++ Standard Template Library contains the function template max(x, y)
which returns either x or y, whichever is larger. max()
could be defined like this:
template <class a> a max(a x, a y) { if (y >= x) return y; else return x; }
This template function can be invoked as a regular function, as in the following example:
std::cout << max(3, 7); //outputs 7
For the above example, the compiler first examines the function arguments 3 and 7 and determines that they are integers. Hence, the compiler finds that template type a
is of type int
for that particular method call. Then, the compiler creates a function in which the method signature is int max(int, int)
. At runtime, whenever the above example code executes, the executable environment (or virtual machine) instantiates the version of that template function that matches the aforementioned method signature.
Template functions can be defined for arguments of any type for which a concrete function can be created by the compiler. If you have defined your own type, you can use operator overloading to define the meaning of <
for your type, thus allowing you to use the max()
function.
Template functions, which support both primitive and class types, also allow the user to utilize standard template libraries such as STL. Template libraries can leverage template functions by allowing the user of the library to define types and operators for those types in nearly unlimited ways.
As a counterexample, the standard type complex
does not define the <
operator because there is no strict order on complex numbers. Therefore max(x, y)
will fail with a compile error if x and y are complex
values. Likewise, other templates that rely on <
cannot be applied to complex
data. Unfortunately, compilers historically generate somewhat esoteric and unhelpful error messages for this sort of error. Ensuring that a certain object adheres to a method protocol can alleviate this issue.
[edit] Class templates
A class template extends the aforementioned template function concept to classes. Class templates are often used to define the methods and sub-types of generic containers. For example, the STL for C++ has a linked list container called list
. The statement list<int>
designates or instantiates a linked-list of type int
. The statement list<string>
designates or instantiates a linked-list of type string
.
A class template usually defines a set of generic functions that operate on the type specified for each instance of the class (i.e., the parameter between the angle brackets, as shown above). The compiler will generate the appropriate function code at compile-time for the parameter type that appears between the brackets.
[edit] Advantages and disadvantages
Some uses of templates, such as the max()
function, were previously fulfilled by function-like preprocessor macros. For example, the following is a C++ max()
macro:
#define max(a,b) ((a) < (b) ? (b) : (a))
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. However, template functions will have run-time overhead when they are not expanded inline.
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, where as macros are substantially more limited.
There are three primary drawbacks to the use of templates:
1) Historically, some compilers exhibited poor support for templates. So, the use of templates could decrease code portability.
2) Many compilers lack clear instructions when they detect a template definition error. This can increase the effort of developing templates, and has prompted the inclusion of Concepts in the next C++ standard.
3) Since the compiler generates additional code for each template type, indiscriminate use of templates can lead to code bloat, resulting in larger executables.
[edit] Generic programming features in other languages
Initially, the concept of templates was not included in some languages, such as Java and C# 1.0. Java's adoption of generics mimics the behavior 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[1]. Some of the advanced template features utilized by libraries such as Boost and STL for template metaprogramming (explicit or partial specialization, default template arguments, template non-type arguments, template template arguments, ...) are not available with generics.