Aller au contenu

Template Classes

Genericity

Like Java, the C++ programming language supports generic functions and generic classes. In C++, generic functions are called template functions and generic classes are called template classes. The motivations are very similar for both languages: how to write several classes that share common behaviors and for which you define the behavior based on an abstract data type.

It is probably easier to explain the principle with a simple example. Say that you want to create a class that does perform some basic arithmetic operations on integers. This is demonstrated in the example program. In this example, the Arithmetic class explicitly uses integers.

Assume that we want to do arithmetic with floating point numbers rather than with integers. Obviously, one can rewrite the Arithmetic class by replacing int with float. This means that we need to rewrite the same class by simply changing the type in all member declarations. This is not very efficient and sustainable. One needs to duplicate important parts of the code, which is also difficult for maintenance.

C++, like Java, allows to do better with the use of template/generic classes.

#include <cstdio>

class Arithmetic {
public:
    Arithmetic(int a, int b) : _a(a), _b(b)
    {
    }

    int add()
    {
        return _a + _b;
    }

    int sub()
    {
        return _a - _b;
    }

private:
    int _a;
    int _b;
};

int main() {
    Arithmetic a1(1, 2);
    printf("Add is %d, sub is %d\n", a1.add(), a1.sub());

    // Put your code here
    return 0;
}

Template Class Declaration

Template classes allow you to instantiate classes with different data types at compile time:

template <typename T>
class Container {
private:
    T data;
public:
    void set(T value) { data = value; }
    T get() { return data; }
};

Then you can use it with different types:

Container<int> intContainer;
Container<double> doubleContainer;
Container<std::string> stringContainer;

Advantages of Templates

  • Code Reusability: Write once, use with any type
  • Type Safety: Checked at compile time
  • No Runtime Overhead: The compiler generates the necessary code
  • Flexibility: Same code works for different data types

Template Specialization

You can also specialize templates for specific types if needed, providing custom implementations for particular data types.

example

#include <cstdio>
#include <cstdint>

template <typename T, uint32_t queue_sz> class Queue {
public:
    // add other methods
    uint32_t getSize() const {
        return queue_sz;
    }
private:
    T array[queue_sz];
};

template <class T> class Arithmetic {
public:
    Arithmetic(T a, T b) : _a(a), _b(b)
    {

    }

    T add()
    {
        return _a + _b;
    }

    T sub()
    {
        return _a - _b;
    }

private:
    T _a;
    T _b;
};

int main() {
    // use Arithmetic with int
    Arithmetic<int> a1(1, 2);
    printf("Add is %d, sub is %d\n", a1.add(), a1.sub());

    // use Arithmetic with float
    Arithmetic<float> a2(1.5, 2.1);
    printf("Add is %f, sub is %f\n", a2.add(), a2.sub());

    // create a queue of char of size 5
    static constexpr uint32_t kCharQueueSize = 5;
    Queue<char, kCharQueueSize> charQueue;
    printf("char queue size is %d\n", charQueue.getSize());

    // create a queue of int of size 10
    static constexpr uint32_t kIntQueueSize = 10;
    Queue<int, kIntQueueSize> intQueue;
    printf("integer queue size is %d\n", intQueue.getSize());

    return 0;
}