|< C++ Implementation In Java | Main | C++ Templates 2 >| Site Index | Download |


 

 

 

 

 

MODULE 24

THE C++ TEMPLATES - AN INTRODUCTION TO STL 1

This type, that type, so many types,

No more type! THE GENERIC TYPES

 

 

 

 

 

My Training Period: xx hours

 

Some notes:

The C++ programming abilities that should be acquired:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

24.1  Introduction

  • Many real applications use common data structure routines such as list, sort, and queue.  A program may require a List of name and another time, a List of messages.  So we can create a List of name program, and then reuse the existing code to create a List of messages program.  Next time we may need another List of address etc.  Again we copy the List of messages program.  These situations happen again and again.

  • If we need to change the original codes, the other codes also may need changes; at the beginning we also have to change the codes regarding the data type because name and messages may implement different data type.  It will become headache isn’t it?

  • It is wiser to create a List program that contains an arbitrary data type that is ready for many data types because the List routine should be the same.  This is called parameterized or generic data type, commonly referred to as template.  Notice that the word data type or type.  This is the word that we are concern about regarding why the template ‘creature’ exists.

  • Template extends the concepts of the reusability.   In the List example, template allows us to implement something like a generic List as shown below, where the any_data_type is its type parameter.

List<any_data_type>

  • Then any_data_type can be replaced with actual types such as int, float, name, messages, address etc as shown below.

List<int>

List<name>

List<messages>

  • When the changes implemented in the

List<any_data_type>

  • Then it should immediately reflected in the other classes, List<int>, List<name> etc.

  • Templates are very useful when implementing generic constructs such as lists, stacks, queues, vectors etc which can be used in any arbitrary data type.  These generic constructs normally found in data structure, search routines and database applications.

  • Designing a type-independent class enables users to choose the desired data type for specific application without having to duplicate code manually.  Furthermore, type independent classes should be portable among different locales and platforms.

  • It provides source code reusability whereas inheritance provides object code reusability.

  • Furthermore, almost all part of the C++ Standard Library is implemented using templates.

  • Generally, templates are functions or classes that are written for one or more types not yet specified. When you use a template, you pass the types as arguments, explicitly or implicitly.

  • Basically, there are two kinds of templates:

  1. Function template.

  2. Class template.

  • For example, the Standard Template Library (STL) generic Algorithm has been implemented using function templates whereas the Containers have been implemented using class template.

  • We will go through the algorithm and container more detail in another Module later on.

24.2  Function Template

#include <iostream>

using namespace std;

 

// function declaration and definition

template <class any_data_type>

any_data_type MyMax(any_data_type Var1, any_data_type Var2)

{

    // if var1 is bigger than Var2, then Var1 is the maximum

    return Var1 > Var2 ? Var1:Var2;

}

24.2.1  Function Template Instantiation

#include <iostream>

using namespace std;

 

// function template declaration and definition

template <class any_data_type>

any_data_type MyMax(any_data_type Var1, any_data_type Var2)

{

    return Var1> Var2 ? Var1:Var2;

}

 

int main()

{

       cout<<"MyMax(10,20) = "<<MyMax(10,20)<<endl;

       cout<<"MyMax('Z','p') = "<<MyMax('Z','p')<<endl;

       cout<<"MyMax(1.234,2.345) = "<<MyMax(1.234,2.345)<<endl;

 

       // some logical error here?

       cout<<"\nLogical error, comparing pointers not the string..."<<endl;

       char* p = "Function";

                   char* q = "Template";

                   cout<<"Address of *p = "<<&p<<endl;

                   cout<<"Address of *q = "<<&q<<endl;

                   cout<<"MyMax(\"Function\",\"Template\") = "<<MyMax(p,q)<<endl;

                   cout<<"Should use Specialization, shown later..."<<endl;

       return 0;

}

 

Output:

 

C++ STL string template

 

24.3  Class Template

template <class any_data_type>

class MyStack

{

private:

    // number of the stack’s element

    int size;

    // top position

    int top;

    // data type pointer

    any_data_type* StackPtr;

 

public:

    // constructor...

    MyStack(int =10);

    // destructor...

    ~MyStack(){delete [ ] StacKPtr;}

    // put in data...

    int push(const any_data_type&);

    // take out data...

    int pop(any_data_type&);

    // test the emptiness...

    int IsEmpty() const {return top == -1;}

    // test the fullness...

    int IsFull() const {return top == size – 1;}

};

  • For your information, the top of the stack is the position occupied by the most recently added element and it should be the last element at the end of the container.  A simple stack is illustrated below.  The real story of stack construction during the function call can be read in C/C++ Compiler, Assembler and Linker.

C++ class template a - stack illustration

  • Another example of the template declaration:

 

template <class any_data_type>

class Vector

{

private:

any_data_type *buffer;

// copy constructor

Vector<any_data_type>   (const Vector <any_data_type> &Var1)

//overloaded assignment operator

Vector<any_data_type>& operator=(const Vector<any_data_type>& Var2)

// destructor

~Vector<any_data_type>();

// other member functions…

any_data_type& operator [ ] (unsigned int index);

const any_data_type& operator [ ] (unsigned int index) const;

}

// destructor definition

template  <class any_data_type>

MyStack<any_data_type >::~MyStack()

{delete [ ] StackPtr;}

// constructor definition

template <class any_data_type>

MyStack<any_data_type>::MyStack()

MyStack<MyClass>

MyStack<float>

MyStack<MessagePtr*>

template <typename any_data_type>

class Vector

{ }

 

24.3.1  Class Template Parameters

template <class any_data_type>

class Vector

{ }

template <class any_data_type, int p>

class Array

{ }

int num = 100;

const int Var1 = 10;

// should be OK, Var1 is a const

Array<float, Var1> Test;

// should be OK, 10 is a const

Array<char, 10> Test1;

// should be OK, constant expression been used

Array<unsigned char, sizeof(float)> Test2;

// not OK, num is not a constant

Array<int, num> Test3;

int ReceiveMsg(const Vector<char*>&);

int main()

{

    // a template used as an argument

    Vector <Vector<char*>  > MsgQ(20);

    // other codes….

    // receive messages

    for(int j = 0; j < 20; j++)

        ReceiveMsg(MsgQ[j]);

    return 0;

}

Vector <Vector<char*>  > MsgQ(20);

 

24.3.2  Default Type Arguments

template <class any_data_type, class S = size_t>

class Vector

{ };

// second argument default to size_t

Vector <int>  TestVar;

Vector <int, unsigned char> short(7);

template <class any_data_type = float, int element = 10>

MyStack{ };

MyStack<>  Var1;

MyStack<float, 10>

#include <iostream>

using namespace std;

 

// primary template with default parameter

template <class any_data_type, int size>

class MyStack

{ };

 

// specialization declaration and definition

// with default arguments will generate error...

template <class any_data_type, int size=100>

class MyStack<int,100>

{ };

 

// do some testing

int main()

{

MyStack<float,100> Var1;

return 0;

}

// a simple class template program example

// ------declaration and definition part--------

template <class any_data_type>

class MyStack

{

private:

// number of the stack's element

int size;

// top position

int top;

// data type pointer

any_data_type* StackPtr;

 

public:

// constructor...

MyStack(int =10);

// destructor...

~MyStack(){delete [] StacKPtr;}

// put in data...

int push(const any_data_type&);

// take out data...

int pop(any_data_type&);

// test the emptiness...

int IsEmpty() const {return top == -1;}

// test the fullness...

int IsFull() const {return top == size - 1;}

};

 

// the main() program

int main()

{

return 0;

}

 

Output:

 

C++ template - a simple STL template

 

24.3.3  Member Function Templates

// normal class

class MyClass

{

         //...

// but, have template member function...

template <class any_data_type>

void MemberFunct(any_data_type)

{ };

};

 

int main()

{

return 0;

}

24.3.4  Nested Template Classes

template <class any_data_type>

class MyClass

{

         // ...

// nested class template

template <class another_data_type>

class NestedClass

{ };

         // ...

};

 

int main()

{ return 0; }

 

tenouk fundamental of C++ object oriented tutorial

 

 

 

 

 

 

 

 

 

 

 

 

 

Further related reading:

 

  1. Source code for this tutorial is available in C++ STL Template source code.

  2. A complete C & C++ Standard Library documentation that includes STL.

  3. Check the best selling C / C++, STL and UML books at Amazon.com.

 

 

 

 

 

 

|< C++ Implementation In Java | Main | C++ Templates 2 >| Site Index | Download |


C++ Templates:  Part 1 | Part 2