Results 1 to 5 of 5

Thread: C++ Templates

  1. #1
    Join Date
    Jan 2008
    Location
    india,kerala-god's own country
    Posts
    14,007

    Default C++ Templates

    This guide will help you and provide a detail information of templates in C ++

    Introduction

    Templates are a feature of the C++ programming language that allows functions and classes to be generic. This allows a function or class to work on many different data types without being rewritten for each one. Thus it helps the programmers when combined with multiple inheritance and operator overloading.

    Advantages

    This is called a symbol that either a function, structure or a class. The interest lies in its templates:

    • Generous: as long as the type parameter provides everything that is used in the symbol template, you can pass any kind
    • Simplicity: it is a symbol code whatever data type is passed as a parameter, making the code much easier to maintain

    Disadvantages

    • As we shall see subsequently the use of template requires some precautions (type name...)
    • The program takes longer to compile.

  2. #2
    Join Date
    Jan 2008
    Location
    india,kerala-god's own country
    Posts
    14,007

    Default

    When using templates?

    The use of templates is particularly relevant to identify containers, i.e. structures that are used to store a collection of objects (a list, a vector, a graph ...).

    The templates are also adapted to define generic algorithms apply to a family of class. For example, it is interesting to encode an algorithm shortest path regardless of the structure graph. Note that the use of functions may be relevant to access weight installed on the arcs of the graph in this case. The class graph pass parameter must then verify a number of prerequisites for the
    algorithm can be applied. If this is not the case the program does not compile.

    What do I put in .Hpp and in .Cpp?

    The C++ is a compiled language, we obviously can not imagine compiling a symbol of all its versions. For example, if we define a template class of vehicle, which I will note my_vector <T> can not imagine compile my_vector <int>, my_vector <char>, my_vector <my_struct> ... knowing that there are an infinite number of types can be passed as parameter.

    That is why a class template is (re) compiled for each type of form in the program. So if I use in my program my_vector <int> and my_vector <char>, only those versions will be compiled. If another program using my_vector <my_vector <double>>, I will just compile my_vector <float> and my_vector <my_vector <float>>. The important point is that the compiler is doing just to find out what versions must be compiled.

    From what has been said, it is deduced that a symbol template can be "pre-" because it is compiled for each instance. It will therefore the following rule:

    If a symbol template is used only in one .Cpp (source file), it can be implemented in this .Cpp . Otherwise, it must be implemented in one .Hpp (header).

    Note:

    It may happen that a file containing a class template has a different extension of headers (.H or.Hpp),
    for example .Tcc - This is a convention notations. Personally, I consider them as fully fledged headers.


    Convention ratings

    The parameters templates are generally rated with a capital (while other types are usually written in small). In practice, it
    is as you want. Personally I denote preceded by a T (for example Tgraph to designate a template parameter representing a graph).

    This may seem trivial but we will see that it's pretty convenient to navigate with typenames and it makes the code more readable.


    Some famous templates

    STL

    The STL (Standard Template Library) is supplied with basic C++ compilers. This library provides a set of generic containers, including:
    std:: vector: vectors (table of elements T-type adjacent to memory), access to O (1)
    std:: Set: sets of T-type elements without duplication and orderly according to the operator <, access to O (log (n))
    std:: list: lists (access to O (n) insertion at the beginning and end of the list O (1))


    BGL

    The HMO (Boost Graph Library) provides classes and generic graph algorithms that go with (algorithms shortest path algorithm afloat, rangelands graph, ...).

    The latter is not present by default but easily moved. For example bug:
    aptitude install libboost-graph-dev

  3. #3
    Join Date
    Jan 2008
    Location
    india,kerala-god's own country
    Posts
    14,007

    Default

    First steps

    To handle templates, you need four things:

    -- Typename keyword: it shows that the type that follows is abstract (or template parameter depends on a parameter template) and that it should be taken into account only when it instantiates.

    -- Keyword template: it indicates that the symbol (structure, class, position) who will monitor takes parameters templates. It is
    written directly after the keyword template settings templates (preceded by the keyword typename, struct, class or type basis depending on the type of template parameter expected) brackets, followed by the symbol written normally. Make sure to separate the rafters (Closing) so that it should not be confused with the operator>>.

    In this example we'll see
    -- How to encode a class template
    -- How to encode a function template
    -- How to encode an operator template
    In this example symbols settings to take just one parameter template, but the approach remains similar settings with several
    templates.

    Example:

    Code:
    template <typename T1, typename T2, ... >
    Type_Typename_t my_function (param1_t p1, param2_t p2, ...)
    { ... }
    Template <typename T1, typename T2, ... >
    Class my_class_t (... );
    Template <typename T1, typename T2, ... >
    My_struct_t struct (... );


    -- The operator::: it allows access to the fields (in particular types) and static methods of a class or a structure. It is not specific to the templates (it applies to classes and structures in general and namespaces). You can see a bit like the '/' directories. Thus std:: vector <int>:: const_iterator means that I go to type const_iterator, stored in the class <int> vector itself encoded in the namespace std.

    We will define our own class of vehicle to illustrate what has been said. Of course in practice be used directly class std:: vector of the STL.

    Code:

    # include <iostream>
    # include <cstdlib>
    # include <ostream>
    template <typename T>
    class my_vector_t {
    protected:
    unsigned size;
    T * data;
    public:
    my_vector_t (unsigned size0 = 0, const T & x0 = T( )): size (size0),
    data ((T *) malloc (sizeof (T) * size0)) { for (unsigned i = 0; i <size; ++ i) data [i] = x0; }
    ~ my_vector_t () { free (data); }
    inline unsigned size () const {return size;}
    inline const T & Operator [] (unsigned i) const {
    if (i> = size ())
    throw: return data [i];}
    inline T & operator [] (unsigned i ) {
    If (i> = size ())
    throw: return data [i]; } }
    template <typename T>
    std:: ostream & operator <<(std:: ostream & out, const my_vector_t <T> & v)
    { unsigned n = v.size ();
    out << "[";
    for (unsigned i = 0; i <n; ++ i)
    out <<v [i] << '';
    out << ']';
    return out; }
    template <typename T>
    void write (const my_vector_t <T> & v)
    { unsigned n = v.size ();
    std::cout << "[";
    for (unsigned i = 0; i <n; ++ i)
    std:: cout << v[i] << ' '; std:: cout << ']'; }
    int main ()
    { my_vector_t <int> v(5), v [0] = 6;
    v [1] = 2;
    v [2] = 3;
    v [3] = 4;
    v [4] = 8;
    write <int> (v)
    std:: cout <<std :: endl;
    write (v);
    std:: cout <<v <<std::endl;
    return 0; }

    At the completion:
    Code:
    [6 2 3 4 8] [6 2 3 4 8] [6 2 3 4 8]

    Anything that is in "early my_vector_t class" and "end my_vector_t class" could be moved to a header (eg my_vector.hpp) can be included by the main program.

  4. #4
    Join Date
    Jan 2008
    Location
    india,kerala-god's own country
    Posts
    14,007

    Default

    Specifications templates

    Nothing prevents specifically to implement a symbol for a set of template parameter. Note that there is no requirement to specify
    all the parameters template. In this case the prototype the "less template" is privileged to remove ambiguities. If we departed the
    previous example:

    Code:

    # include "my_vector.hpp"
    void write (const my_vector_t <int> & v)
    { unsigned n = v.size ();
    std::cout << "{";
    for (unsigned i = 0; i <n; ++ i)
    std:: cout <<v [i] << '';
    std:: cout << '}'; }
    int main ()
    { my_vector_t <int> v (5);
    v [0] = 6;
    v [1] = 2;
    v [2] = 3;
    v [3] = 4;
    v [4] = 8;
    write <int> (v);
    std:: cout <<std:: endl;
    write (v);
    std:: cout <<std:: endl ;
    std:: cout <<v <<std:: endl;
    return 0; }

    At the completion:
    Code:
    [6 2 3 4 8] (6 2 3 4 8) [6 2 3 4 8]


    Template default

    It is also possible to specify a template parameter default in the same manner as a parameter function.

    For example:
    Code:
    template <typename T = int>
    class my_vector_t { //... };
    int main ()
    { my_vector <> v ;
    return 0; }

    Some famous examples of templates default in the STL function comparison, used in std:: set, is initialized by default std:: less
    (function comparison based on <). So you can write indifferently:
    Quote:
    std:: set <int> s; std:: set <int, std:: less <int>> s_;

  5. #5
    Join Date
    Jan 2008
    Location
    india,kerala-god's own country
    Posts
    14,007

    Default

    Retrieving settings templates, types and static methods of a class template

    A bargain with classes templates, is making typedef (in public) to easily retrieve settings templates. Example: I have a class c1 <T>
    and I want to recover the type T. This will be possible through and typedef typename.

    Code:

    template <typename T> typedef struct (my_class_t T data_t;);
    int main () { typedef my_vector_t <int>: data_t data_t; }

    However we can not implement the operator:: that if a member of the left is not an abstract data type (i.e. dependent on a type
    template not yet rated). For example, if I want to manipulate the typedef "const_iterator" of class std:: vector provided by the STL,
    if the parameters templates std:: vector are not affected the program will refuse to compile:

    Code:
    void write (const std:: vector <int> & v)
    { std:: vector <int>:: const_iterator lives (v.begin (), sells (v.end ());
    for (; lives! = sells; ++ lives) std:: cout <<* lives " '';}
    template <typename T>
    void write (const std:: vector <int> & v)
    { std::vector <T>::const_iterator lives (v.begin(), sells(v.end()); // ERROR!
    for (; lives! = sells; ++ lives) std:: cout <<* lives " '';}

    Here the std:: vector <T> is located to the left of a: and depends on a parameter template. This is where typename comes in.

    Code:

    template <typename T>
    void write (const std:: vector <int> & v)
    { typename std::vector <T>::const_iterator lives(v.begin(), sells(v.end());
    for ( ; lives! = sells; ++ lives) std:: cout <<* lives " '';}

    Note that when the type of a left: depends on a parameter template, it must be preceded by a typename. Given that the types quickly become heavy to handle, it is wise to make typedef. In another example, more complicated, it gives for example:
    Code:
    typedef typename std::vector <typename std::vector <T>::const_iterator>::const_iterator mon_type_t


    Templates recursive

    It is possible to define recursive templates (if so). An example:
    Code:
    # include <iostream>
    template <int N>
    int fact () { return N * fact <N-1> (); }
    template <>
    int fact <0> () {return 1;}
    int main ()
    { std: : cout <<fact <5> () <<std:: endl; return 0; }

    Here the interest is fairly moderate as we compile concrete fact <5>, fact <4> ... fact <0> is really just to give a simple example
    template recursive.

    What interest of a template recursive coup? Well a boost, the template allows recursive implement Tuples generic! For small curious that stands in / usr / include / boost / tuple / detail / tuple_basic.hpp, so I will not elaborate further ;-)


    Tester values type template

    It is possible boost to verify whether a type template is a type expected and block the compilation as appropriate. Given that it
    uses the library boost, I just give a brief example:

    <boost/type_traits/is_same.hpp> # include # include
    <boost/static_assert.hpp> template <typename T> struct
    my_struct_Test_int { BOOST_STATIC_ASSERT ((boost: is_same <T,int>: value)) / / .. . };

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •