1

Previous: Multiple files Up: C++ basics Next: Templates and inheritance

This is an automatically generated documentation by LaTeX2HTML utility. In case of any issue, please, contact us at info@cfdsupport.com.

Templates

Templates in C++ are yet another means to increase code re-usability and thus decrease code multiplicity. It is possible to define a template function, or even the whole template class. Simple modification of the previous example is used in following code. Files are in training/cpp_tutorial in the directory templates. The class Array used in the previous example is unsatisfactory in sense, that it is solely for arrays of a type double. What if the same functionality is needed for a type of integer? One possibility is of course to copy the whole class and change few occurrences of double into integer and compile again. However, this approach potentially creates new heaps of code, that is very repetitive. Instead, it is more efficient to use templates.

A template class is best thought of as a recipe for creation of an actual class. When all ingredients are provided compiler creates an actual class.

See the declaration of the template class Array in the file Array.h:

#ifndef ARRAY_H
#define ARRAY_H
 
#include  // for assert()
 
template  // This is a template class, the user will provide the data type for Type
class Array
{
private:
    int m_length;
    Type *m_data;
 
public:
 
    
    Array(int length);
 

    ~Array();
 
 
    Type& operator[](int index);
 

    int getLength();
};
 
 
#endif

It is very similar to the class Array defined in the previous example, but this time, instead of fixing the type of the array to double, it expects to be provided with a type through the template parameter Type, for which it will be instantiated. Implementation in Array.cpp is also very similar:

#include "Array.h"

template 
Array::Array(int length)
{
    m_data = new Type[length];
    m_length = length;
}


template 
Array::~Array()
{
    delete[] m_data;
}


template 
Type& Array::operator[](int index)
{
    assert(index >= 0 && index < m_length);
    return m_data[index];
}

template  
int Array::getLength() { return m_length; }


template class Array;
template class Array;

As a matter of fact, functions  Array() and getLength() are completely the same, except the template declaration. A notable novelty is on lines 29 and 30. The compiler has to be told at the compilation time, which classes it should create from the template. In another words, we provide the Type, that is missing for the recipe to be complete. In this case, we want to create an Array for a type double and a type int, but it can be simply extended to any type without the need to modify implementation of the class. This approach is called explicit instantiation, since we explicitly and ahead of time instantiate classes by providing the template parameters. See the example of use in file main.cpp:

#include 

#include "Array.h"

int main()
{
    Array arrayOfInt = Array(10);
    Array arrayOfDouble = Array(10);

    for(int i = 0; i<10; ++i)
    {
        arrayOfInt[i] = 2*i;
        arrayOfDouble[i] = 2*i + 0.5;
    }

    for(int i = 0; i<10; ++i)
    {
        std::cout << i << "\t" << arrayOfInt[i] << "\t" << arrayOfDouble[i] << std::endl;
    }
}

Compilation of the program could look like this:
196

# g++ -c Array.cpp -o Array.o
# g++ -c main.cpp -o main.o
# g++ main.o Array.o -o templates
197

# x86_64w64-mingw32-g++ -c Array.cpp -o Array.o
# x86_64w64-mingw32-g++ -c main.cpp -o main.o
# x86_64w64-mingw32-g++ main.o Array.o -o templates

Running the program will result in following output:

# ./templates
# 0 0 0.5
# 1 2 2.5
# 2 4 4.5
# 3 6 6.5
# 4 8 8.5
# 5 10 10.5
# 6 12 12.5
# 7 14 14.5
# 8 16 16.5
# 9 18 18.5

 

It is better to think about Array and Array as of two separate classes, instead of “class with parameter”. It is not possible to simply use any type, because we compiled Array.cpp only for two type (double and intArray and Array. For example, using the following code will cause an error during the compilation:

    Array arrayOfChar = Array(10);

To make it work, Array.cpp needs to be extended as follows:

template class Array;

Another possibility would be to include the file Array.cpp into the main.cpp. This way, compiler sees both template class usage and definition in one file and can instantiate template classes as needed during compilation. Still, it is not possible to instantiate template classes during runtime, so one needs to know (or guess), which classes will be needed and one must have them compiled in advance.