Template (programming)

Template (programming)

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.

Contents

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 template max(x, y) which returns either x or y, whichever is larger. max() could be defined like this, using the following template:

template <typename Type>
Type max(Type a, Type b) {
    return a > b ? a : b;
}

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.

#include <iostream>
 
int main()
{
  // This will call max <int> (by argument deduction)
  std::cout << max(3, 7) << std::endl;
  // This will call max<double> (by argument deduction)
  std::cout << max(3.0, 7.0) << std::endl;
  // This type is ambiguous, so explicitly instantiate max<double>
  std::cout << max<double>(3, 7.0) << std::endl;
  return 0;
}

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-constructible type for which the expression (y < x) is valid. For user-defined types, this implies that the less-than operator must be overloaded.

Class templates

A class template provides a specification for generating classes based on parameters. Class templates are commonly used to implement containers. A class template is instantiated by passing a given set of types to it as template arguments.[1] The C++ Standard Library contains many class templates, in particular the containers adapted from the Standard Template Library, 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 specialization. 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 the maximum() function, were previously fulfilled by function-like preprocessor macros. For example, the following is a C++ maximum() macro:

  #define maximum(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. 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:

  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 development of Concepts for possible inclusion in a future 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.
  4. Because a template by its nature exposes its implementation, injudicious use in large systems can lead to longer build times.
  5. 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.
  6. Templates of Templates (nesting) are not supported by all compilers, or might have a max nesting level.
  7. Templates are in the headers, which require a complete rebuild of all project pieces when changes are made.
  8. 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:

  foo (a < b, c > d) ;

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 Java 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.[2] 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.[3] 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:

template Factorial(ulong n)
{
    static if( n <= 1 )
        const Factorial = 1;
    else
        const Factorial = n * Factorial!(n-1);
};

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 functions.

// Simple example, assumes all arguments are of the same type.
T[0] max(T...)(T args) {
    static assert(args.length > 1, "Insufficient arguments.");
    // T[0] is the type of the first argument,
    // args[0] is the first argument.
    T[0] max = args[0];
    // Tuple can be iterated over and sliced like an array.
    foreach (arg; args[1 .. $])
        if (arg > max)
            max = arg;
    return max;
}

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.[4]

template Foo(int N) if (N & 1)    {...} // A
template Foo(int N) if (!(N & 1)) {...} // B
 
Foo!(3)    // Instantiates A
Foo!(64)   // Instantiates B
 
template Bar(T) if (isFloatingPoint!T) {...}
 
Bar!(3.5) // Instantiates Bar
Bar!(3)   // Fails

Something similar can be done in C++ with Boost enable_if.[5]

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:

// Induction 
 
template <int N> struct Factorial {
  static const int value = N * Factorial<N - 1>::value;
};
 
// Base cases via template specialization:
 
template <>
struct Factorial<0> {
  static const int value = 1;
};
 
template <>
struct Factorial<1> {
  static const int value = 1;
};

With these definitions, one can compute, say 6! at compile time using the expression Factorial<6>::value.

See also

References

  1. ^ Vandevoorde, Daveed; Josuttis, Nicolai (2002). C++ Templates: The Complete Guide. Addison Wesley. ISBN 0-201-73484-2. 
  2. ^ Differences Between C++ Templates and C# Generics (C# Programming Guide)
  3. ^ (D) Templates Revisited
  4. ^ (D) Template Constraints
  5. ^ Boost enable_if templates

Wikimedia Foundation. 2010.

Игры ⚽ Нужно решить контрольную?

Look at other dictionaries:

  • Template — may mean:*a stencil, pattern or overlay used in graphic arts (drawing, painting, etc) and sewing to replicate letters, shapes or designs *a pre developed page layout in electronic or paper media used to create new pages from the same design,… …   Wikipedia

  • 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… …   Wikipedia

  • Programming paradigm — Programming paradigms Agent oriented Automata based Component based Flow based Pipelined Concatenative Concu …   Wikipedia

  • Template Haskell — is an experimental language extension to the programming language Haskell implemented in the Glasgow Haskell Compiler (version 6 and later).In early incarnations it was also known as Template Meta Haskell.It allows compile time metaprogramming… …   Wikipedia

  • Programming language — lists Alphabetical Categorical Chronological Generational A programming language is an artificial language designed to communicate instructions to a machine, particularly a computer. Programming languages can be used to create programs that… …   Wikipedia

  • Programming in the large and programming in the small — Programming paradigms Agent oriented Automata based Component based Flow based Pipelined Concatenative Concurrent computin …   Wikipedia

  • Template Oriented Programming — In computer programming, Template oriented programming (TOP) is a programming paradigm that focuses on templates to accomplish a programmer’s goals. Template oriented programming is a more general version of generic programming in which the… …   Wikipedia

  • Template processor — A template processor (also known as a template engine or a template parser )is software or a software component that is designed to combine one or more templates with a data model to produceone or more result documents.cite book last = Niemeyer… …   Wikipedia

  • Template engine (web) — A (web) template engine is software that is designed to process web templates and content information to produce output web documents. It runs in the context of a template system.pecific types of template engines Template engine is ordinarily… …   Wikipedia

  • Template method pattern — [ LePUS3 ( [http://lepus.org.uk/ref/legend/legend.xml legend] ) ] In software engineering, the template method pattern is a design pattern.It is a so called behavioral pattern, and is unrelated to C++ templates.IntroductionIn a template pattern,… …   Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”