|< C++ Templates 1 | Main | C++ Characters & Strings 1 >| Site Index | Download |


 

 

 

 

 

 

MODULE 24a

THE C++ TEMPLATES - AN INTRODUCTION TO Standard Template Library (STL) 2

This type, that type, so many types,

No more type! THE GENERIC TYPES

 

 

 

 

 

My Training Period: xx hours

 

The C++ programming skills that should be acquired:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

24.4  Class Template Instantiation

  • A template instantiation is a process of instantiate a real class from a template for our real usage.  It provides general class template with potentially infinite data types.

  • The following is a program example of a class template instantiation.  It is bundled in one program, one file for our study convenience.

#include <iostream>

using namespace std;

 

// class template declaration part

// test.h

template <class any_data_type>

class Test

{

public:

// constructor

Test();

// destructor

~Test();

// function template

any_data_type Data(any_data_type);

};

 

template <class any_data_type>

any_data_type Test<any_data_type>::Data(any_data_type Var0)

{return Var0;}

 

// a class template definition part

// should be in the same header file with the class template declaration

// constructor

template <class any_data_type>

Test<any_data_type>::Test()

{cout<<"Constructor, allocate..."<<endl;}

 

// destructor

template <class any_data_type>

Test<any_data_type>::~Test()

{cout<<"Destructor, deallocate..."<<endl;}

 

// the main program

int main()

{

Test<int> Var1;

Test<double> Var2;

Test<char> Var3;

Test<char*> Var4;

cout<<"\nOne template fits all data type..."<<endl;

cout<<"Var1, int = "<<Var1.Data(100)<<endl;

cout<<"Var2, double = "<<Var2.Data(1.234)<<endl;

cout<<"Var3, char = "<<Var3.Data('K')<<endl;

cout<<"Var4, char* = "<<Var4.Data("The class template")<<"\n\n";

return 0;

}

 

Output:

 

C++ templates programming - a class template

#include <iostream>

using namespace std;

 

// a class template declaration part

// test.h file

template <class any_data_type>

class Test

{

public:

// constructor

Test();

// destructor

~Test();

// function template

any_data_type Data(any_data_type);

};

 

template <class any_data_type>

any_data_type Test<any_data_type>::Data(any_data_type Var0)

{return Var0;}

 

// a class template definition part

// should be in the same header file with the class template declaration

// a constructor

template <class any_data_type>

Test<any_data_type>::Test()

{cout<<"Constructor, allocate..."<<endl;}

 

// a destructor

template <class any_data_type>

Test<any_data_type>::~Test()

{cout<<"Destructor, deallocate..."<<endl;}

// do not run this program

// make sure there is no error such as typo etc

// test.cpp file

// compile and run this program

// the main program

int main()

{

Test<int> Var1;

Test<double> Var2;

Test<char> Var3;

Test<char*> Var4;

cout<<"\nOne template fits all data type..."<<endl;

cout<<"Var1, int = "<<Var1.Data(100)<<endl;

cout<<"Var2, double = "<<Var2.Data(1.234)<<endl;

cout<<"Var3, char = "<<Var3.Data('K')<<endl;

cout<<"Var4, char* = "<<Var4.Data("The class template")<<"\n\n";

return 0;

}

 

Output:

 

C++ class template program example

#include <iostream>

using namespace std;

 

template <class any_data_type>

class Test

{

    public:

         // a constructor

         Test(){ };

         // a destructor

         ~Test(){ };

         // member function templates...

         any_data_type Funct1(any_data_type Var1)

         {return Var1;}

         any_data_type Funct2(any_data_type Var2)

         {return Var2;}

};

 

// do some testing

int main()

{

// implicit instantiation generates class Test<int>...

Test<int> Var1;

// implicit instantiation generates class Test<double>...

Test<double> Var2;

 

cout<<"Implicit instantiation..."<<endl;

// and generates function Test<int>::Funct1()

cout<<"Var1 = "<<Var1.Funct1(200)<<endl;

// and generates function Test<double>::Funct2()

cout<<"Var2 = "<<Var2.Funct2(3.123)<<endl;

return 0;

}

 

Output:

 

C++ templates program - implicit instantiation of a class template

#include <iostream>

using namespace std;

 

template <class any_data_type>

class Test

{

    public:

       // a constructor

       Test(){ };

       // a destructor

       ~Test(){ };

       // a member functions...

       any_data_type Funct1(any_data_type Var1)

       {return Var1;}

       any_data_type Funct2(any_data_type Var2)

       {return Var2;}

};

 

// explicit instantiation of class Test<int>

template class Test<int>;

// explicit instantiation of class Test<double>

template class Test<double>;

 

// do some testing

int main()

{

    Test<int> Var1;

    Test<double> Var2;

    cout<<"Var1 = "<<Var1.Funct1(200)<<endl;

    cout<<"Var2 = "<<Var2.Funct2(3.123)<<endl;

    return 0;

}

 

Output:

 

C++ template programming - an explicit instantiation of a class template

 

24.5  Function Template Instantiation

// implicit instantiation

#include <iostream>

using namespace std;

 

template <class any_data_type>

any_data_type MyMax(any_data_type Var1, any_data_type Var2)

{

       return Var1 > Var2 ? Var1:Var2;

}

 

// do some testing

int main()

{

    int p;

    char q;

    p = MyMax(100, 200);

    q = MyMax('k', 'K');

    // implicit instantiation of MyMax(int, int)

    cout<<"MyMax(100, 200) = "<<p<<endl;

    // implicit instantiation of MyMax(char, char)

    cout<<"MyMax('k', 'K') = "<<q<<endl;

    return 0;

}

 

Output:

 

C++ STL implicit instantiation of function templates

 

// an explicit instantiation

#include <iostream>

using namespace std;

 

template <class any_data_type>

any_data_type Test(any_data_type Var1)

{

       return Var1;

}

 

// an explicit instantiation of Test(int)

template int Test<int>(int);

 

// do some testing

int main()

{

cout<<"Var1 = "<<Test(100)<<endl;

return 0;

}

 

Output:

 

C++ template programming - an explicit instantiation of function templates

#include <iostream>

using namespace std;

 

template <class any_data_type>

class TestVirt

{

    public:

       virtual any_data_type TestFunct(any_data_type Var1)

       {return Var1;}

};

 

// do some testing

int main()

{

    // implicit instantiation of TestVirt<int>

    TestVirt<int> Var1;

    cout<<"Var1.TestFunct(100) = "<<Var1.TestFunct(100)<<endl;

    return 0;

}

 

Output:

 

C++ template programming - instantiating the virtual member functions

 

24.6  Class Template Specialization

  • A specialization consists of a template name followed by a list or arguments in angle brackets and it is a specialize class template instantiation.

  • When we instantiate the class template, from a general class template, we make the class template special to suit our specific programming tasks.

  • A specialization can be used exactly like any other normal class and here, compiler will generate a specialized concrete instance from the generic of the templates.  For examples:

// an object instantiation

Vector<int> Var;

// as function parameter

int Funct(Vector <float>&);

// used in sizeof expression

size_t p = sizeof(Vector <char>);

// used in class object instantiations

class MyTestVector: private Vector<std::string>

{ };

Vector <Date> Var1;

Vector <string> Var2;

  • The compiler actually instantiates only the necessary member functions of a given specialization or generate when there is a request.

 

24.7  The Primary, Partial and Specialization Class Template

#include <iostream>

#include <string>

using namespace std;

 

template <class any_data_type>

inline any_data_type MyMax(const any_data_type& Var1, const any_data_type& Var2)

{

    cout<<"Checking..."<<endl;

    return Var1 < Var2 ? Var2 : Var1;

}

 

// do some testing

int main()

{

    int Highest = MyMax(7, 20);

    char p = MyMax('x' , 'r');

    string Str1 = "Class", Str2 = "Template";

    string MaxStr = MyMax(Str1, Str2);

   

    cout<<"The bigger between 7 and 20 is "<<Highest<<endl;

    cout<<"The bigger between 'x' and 'r' is "<<p<<endl;

    cout<<"The bigger between \""<<Str1<<"\" and \""<<Str2<<"\" is "<<MaxStr<<"\n\n";

    const char *Var3 = "Class";

    const char *Var4 = "Template";

    const char *q = MyMax(Var3, Var4);

    cout<<"Logical error, comparing the pointer, not the string..."<<endl;

    cout<<"Address of the *Var3 = "<<&Var3<<endl;

    cout<<"Address of the *Var4 = "<<&Var4<<endl;

    cout<<"The bigger between \""<<Var3<<"\" and \""<<Var4<<"\" is "<<q<<endl;

    cout<<"Need specialization here..."<<endl;

    return 0;

}

 

Output:

 

C++ STL class template primary and specialization program example

 

24.7.1  Implementing The Specialization

#include <iostream>

#include <string>

// for strcmp()

#include <cstring>

using namespace std;

 

// primary template, for all type

template <class any_data_type>

any_data_type MyMax(const any_data_type Var1, const any_data_type Var2)

{

       cout<<"Primary template..."<<endl;

       return Var1 < Var2 ? Var2 : Var1;

}

 

// specialization for const char *, empty parameter list

template <>

const char *MyMax(const char *Var1, const char *Var2)

{

       cout<<"Specialization..."<<endl;

       // comparison for const char *

       return (strcmp(Var1, Var2)<0) ? Var2 : Var1;

}

 

// do some testing

int main()

{

    // call primary

    int Highest = MyMax(7, 20);

    // call primary

    char p = MyMax('x' , 'r');

    string Str1 = "Class", Str2 = "Template";

    // call primary

    string MaxStr = MyMax(Str1, Str2);

    cout<<"The bigger between 7 and 20 is "<<Highest<<endl;

    cout<<"The bigger between 'x' and 'r' is "<<p<<endl;

    cout<<"The bigger between \""<<Str1<<"\" and \""<<Str2<<"\" is "<<MaxStr<<"\n\n";

    // call specialization

    const char *Var3 = "Class";

    const char *Var4 = "Template";

    const char *q = MyMax(Var3, Var4);

    cout<<"The bigger between \""<<Var3<<"\" and \""<<Var4<<"\" is "<<q<<endl;

    return 0;

}

 

Output:

 

C++ STL class template specialization program example

 

24.7.2  Partial Specialization

#include <iostream>

using namespace std;

 

// general, justice for all type:-)

template <class any_data_type>

any_data_type Test(any_data_type Var1)

{return Var1;}

 

// partial specialization for all pointers type

template <class any_data_type>

any_data_type * Test(any_data_type *Var2)

{return Var2;}

 

// specialization, just for const char *

template <>const char * Test(const char *Var3)

{return Var3;}

 

// do some testing

int main()

{

    int p = 5;

    // calls Test(any_data_type

    int q = Test(p);

    double r = Test(3.1234);

    cout<<"General types = "<<q<<endl;

    cout<<"General types = "<<r<<endl;

    // calls Test(any_data_type*)

    int *s = Test(&p);

    char *t = "Partial lor!";

    cout<<"Partial types = "<<s<<endl;

    cout<<"Partial types = "<<t<<endl;

    // calls Test(const char *)

    const char *u = Test("Specialized!");

    cout<<"Specialization type = "<<u<<endl;

    return 0;

}

 

Output:

 

C++ STL class template partial specialization program example

 

24.7.3  Template Function Specialization

#include <iostream>

using namespace std;

 

template <class any_data_type>

any_data_type MyMax(any_data_type Var1, any_data_type Var2)

{

    return Var1 > Var2 ? Var1:Var2;

}

 

// specialization of MyMax() for char *

template<>char* MyMax(char* Var3, char* Var4)

{

    return strcmp(Var3,Var4)> 0 ? Var3:Var4;

}

 

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;

       char* Var3 = "Function";

       char* Var4 = "Template";

       cout<<"\nTesting...."<<endl;

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

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

       cout<<"MyMax(\"Function\",\"Template\") = "<<MyMax(Var3,Var4)<<endl;

       return 0;

}

 

Output:

 

C++ STL template function specialization program example

 

24.8  typename Keyword

template <class any_data_type>

class MyClass

{

typename any_data_type::another_data_type * ptr;

//...

};

 

int main()

{

return 0;

}

any_data_type::another_data_type * ptr

MyClass<Test> x;

class Test

{

typedef int another_data_type;

...

};

class Test

{

class another_data_type;

...

};

template <typename any_data_type>

class MyClass

{ };

// *******template.cpp**********

#include <iostream>

#include <string>

// for strcmp()

#include <cstring>

using namespace std;

 

// primary template, for all type

template <class any_data_type>

any_data_type MyMax(const any_data_type Var1, const any_data_type Var2)

{

       cout<<"Primary template..."<<endl;

       return Var1 < Var2 ? Var2 : Var1;

}

 

// specialization for const char *, empty parameter list

template <>

const char *MyMax(const char *Var1, const char *Var2)

{

       cout<<"Specialization..."<<endl;

       // comparison for const char *

       return (strcmp(Var1, Var2)<0) ? Var2 : Var1;

}

 

// do some testing

int main()

{

    // call primary

    int Highest = MyMax(7, 20);

    // call primary

    char p = MyMax('x', 'r');

    string Str1 = "Class", Str2 = "Template";

    // call primary

    string MaxStr = MyMax(Str1, Str2);

    cout<<"The bigger between 7 and 20 is "<<Highest<<endl;

    cout<<"The bigger between 'x' and 'r' is "<<p<<endl;

    cout<<"The bigger between \""<<Str1<<"\" and \""<<Str2<<"\" is "<<MaxStr<<"\n\n";

    // call specialization

    const char *Var3 = "Class";

    const char *Var4 = "Template";

    const char *q = MyMax(Var3, Var4);

    cout<<"The bigger between \""<<Var3<<"\" and \""<<Var4<<"\" is "<<q<<endl;

    return 0;

}

           

[bodo@bakawali ~]$ g++ template.cpp -o template

[bodo@bakawali ~]$ ./template

 

Primary template...

Primary template...

Primary template...

The bigger between 7 and 20 is 20

The bigger between 'x' and 'r' is x

The bigger between "Class" and "Template" is Template

 

Specialization...

The bigger between "Class" and "Template" is Template

 

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++ Templates 1 | Main | C++ Characters & Strings 1 >| Site Index | Download |


C++ Templates:  Part 1 | Part 2