Template (C )

Templates (English for stencils or templates) are means to Typparametrierung in programming languages. Templates allow generic programming and type-safe containers.

Is an example of a programming language that includes the template language elements. In the C standard library templates to provide type-safe containers such as lists, and to implement generic algorithms, as used, for instance sorting method. The templates in C are much inspired by the parameterizable modules in CLU and Generics in Ada.

In other programming languages ​​(e.g. Java or C # ), there is the concept of the generic type, which is a related concept of templates. However, generic types do not represent code generators, but only allow type-safe containers.

  • 2.1 Specialization in class Templates
  • 2.2 Partial specialization
  • 2.3 specialization in function templates
  • 3.1 Type Parameter
  • 3.2 Non- type parameters
  • 3.3 Template templates
  • 3.4 packs parameter

Types of Templates

There are two types of C templates: function templates and class templates.

Function templates

A function template (also wrongly called template function ) behaves like a function that accepts arguments of different types or different return types supplies. The C standard library contains, for example, the function template std :: max ( x, y), which returns the larger of the two arguments. It could be as defined as follows:

Template T max (T x, T y) {    T value;    if ( x < y)      value = y;    else      value = x;    returnValue; } This template can be called just like a function:

Cout << max ( 3, 7); / / Returns 7 of Based on the arguments, the compiler decides that it is a call to max ( int, int), and produces a variant of the function, in which the generic type T is set to int.

The template parameter may also be specified explicitly:

Cout << max (3, 7); / / Are also "7" from The function template max () can instantiate for each type for which the comparison x < y is a well-defined operation. With user-defined types to make of operator overload use to determine the meaning of < for the type and thereby enable the use of max () for the type in question.

In interaction with the C standard library is a tremendous functionality for user-defined types opens by defining some operators. Just by the definition of a comparison operator < ( strict weak ordering ) the standard algorithms std :: sort (), std :: be stable_sort (), and std :: binary_search () applicable for the user-defined type.

Class templates

A class template (also wrongly called template class ), applies the same principle to classes. Class templates are often used to create generic containers. For example, the C standard library contains a container that implements a linked list. To create a linked list of int to write std :: list . A linked list of objects of the data type std :: string to std :: list is . With a set list of standard features is defined, which are always available, regardless of what one specifies as an argument type in the angle brackets. The values ​​in brackets are called parameters. If a class template and its parameters will be passed to the compiler, it can mint the template. He created this for each parameter type your own template class. This is an ordinary class, just like any other. The terms class template and template class can be distinguished from each other here. How object and class is the template class an instance of a class template.

Templates are used for both with class as well as for defined with struct and union classes. Namespaces ( German: namespaces ) can, however, do not create it as a template. One way to create type definitions using " typedef " as a template, was added with C 11.

Heredity

Class templates can occur as a base as well as a derived class like normal classes in inheritance hierarchies.

Not even when the template parameters are in an inheritance relationship - If a class template pronounced with various class parameters, these are generally in no inheritance relation.

Class Base { ...}; class Derived: public Base { ...};   Base * b = new Derived; / / OK. Automatic type conversion, because the base class. std :: vector * vb = new std :: vector ; / / ERROR! There are mainly two reasons why such conversions are not allowed:

For one, there are technical reasons for this: A std :: vector stores its elements in an array of contiguous addresses. Now, if an object of type Derived is a different size than an object of type Base, then the memory layout of a std :: vector no longer matches that of a std :: vector and the access to the elements would fail.

On the other hand, it has also programmatically logical reasons: A container that contains elements of a base class that refers to elements whose data type is base or derived from Base. It is thus more powerful than a container that can only hold elements of type Derived.

If a conversion of different forms of the same class templates - such as boost :: smart_ptr - makes sense, a type conversion operator must be defined for it explicitly.

Specialization

Templates can specialize, that is, one can class and function templates implement separately (for certain data types as template arguments ). This allows a more efficient implementation for certain selected data types, without changing the interface of the template. Of making many implementations of the C standard library (for example, the GCC) use.

Specialization of class templates

The container class std :: vector of the C standard library can be implemented for the element type bool as a bitmap to save space. Also, the class template std :: basic_string takes the information to deal with the individual characters of the structure char_traits specialized char and wchar_t for example, the data type.

The declaration of specializations similar to that of normal templates. However, the keyword template empty following angle brackets, and the function or class name followed by the template parameter.

Template < > class vector {    / / Implementation of vector as a bitmap }; Partial specialization

Furthermore, there are also the so-called partial specialization which enables the treatment of special cases within a template.

Template class matrix {    / / Implementation of a Matrix class };   template class matrix {    / / Implementation of a single-column matrix class }; The instantiation runs in the specialized class is basically the same as it is generated, only the code from another template class, namely the specialization:

Int main () {      Matrix < 3,3 > a; / / First Class      Matrix < 15.1 > b; / / Partial specialized class template (second class) } It is important to mention that both classes are independent, that is, they do not inherit constructors or destructors or member functions or data elements from each other.

Specialization of function templates

In contrast to class template function templates are not part spezialisierbar (only complete) according to standard. However, it is not generally recommended by the specialization of function templates, as the rules for determining the " best fit " function otherwise can lead to unintuitive results.

Overloading of Function Templates with other function templates can in most cases reach the same as the ( ineligible) partial specialization. The extension itself usually runs very intuitive from:

/ / Generic function template void f (T a, U b ) {}   / / Overweight function template template void f (T a, int b ) {}   / / Fully specialized; still template template < > void f ( int a, int b ) {} Here, however, it must be noted that an explicit call as f ( ) does not lead to the desired result. This call would call the generic function instead of the fully specialized. A call to f () calls, however, not the first overloaded template function on, but the fully specialized. Fails to make explicit calls normally everything works as it seems logical (f ( 3, 3 ) calls the fully specialized function, f ( 3.5, 5) the partially specialized ( first overloaded function ) and f ( 3.5, 2.0 ) the generic ). With this type of specialization so you should be careful and, if possible, completely specialize same.

If for any reason this technique is not applicable in this particular case - for example, if a template to be specialized by class methods without having to extend the class definition - so you can relocate the problem of specialization in a template of a helper class:

Class Example {    private:      template      struct Frobnicator      {        static T do_frobnicate (T param);      };      public:      template      Frobnicate T (T param); };   template Example :: frobnicate T (T param) {    / / Frobnicator to do the actual work    return Frobnicator :: do_frobnicate ( param); }   template T Example :: Frobnicator :: do_frobnicate (T param) {    / / Default implementation ... }   template < > int Example :: Frobnicator :: do_frobnicate (int param) {    / / Ints are " frobnifiziert " in other ways    return ( param << 3 ) (param % 7) - param foobar; } Template parameter

Templates can have four types of parameters: Type Parameter, Non- type parameters, template parameters and so-called packs parameters that templates with a variable number of parameters can be defined.

Type parameter

Templates with type parameters are similar to the generic types of other programming languages. As a type parameter, any data type can be used, depending on how the type parameter within the template, the amount of parameter types that the template can be instantiated is limited.

The container of the C standard library use among other type parameter to ask for all data types, user-defined, appropriate container for disposal.

Template class Vector { public:     Vector (): rep ( 0) { }     Vector ( int _size ): rep (new T [ _size ] ), size ( _size ) {}     ~ Vector () { delete [ ] rep; }     / / ... private:     T * rep;     int size; }; Non- type parameters

Non- type parameters ( engl. non -type template parameters ) are constant, known at compile time, values ​​with which sizes, processes or predicates can be passed as a template parameter. As a non - type template parameters are allowed:

  • Integer constants (including character constants ),
  • Pointer constants (data and function pointers, including pointers to member variables and functions) and
  • String constants.

Find use non - type parameters, eg as of size for std :: array or a sort and search criterion in many algorithms in the standard library, such as std :: sort, std :: std :: for_each or find_if.

Template Templates

The template - template structures are referred to, in which templates apply templates as parameters. You are a further abstraction mechanism. In the following example, both the type and the container used is specified; the latter with the aid of a template template parameter:

Template < template class Container, typename Type> class Example {    Container > baz; }; Example of usage:

Example example; Packs parameters

Since C 11 it is possible to define a variable number of templates from the template parameters. These are - as with functions and macros with variable number of parameters - marked with ...:

Template class tuple {     Omitted / / Definition };   / / Use: tuple < int, int, char, std :: vector , double > t; References

Advanced Topics

  • C metaprogramming
157924
de