Template Definitions
We can define our own function and class templates to be instantiated and used with multiple different types, similar to the STL algorithms and classes.
Function Templates
- Can use to define generic function with abstract param types
- Use
template<class Tname>before prototype and function definition - Use
Tnameas type in function - Compiler generates the actual functions by substituting types of arguments in the various function calls
Example:
template <class T> // generic class type name T
T cubeit(T num) // header using type T
{
return num * num * num; // assumes * operation defined for type T
}
int main(void) {
cubeit(3);
}
Class Templates
For a simple type templated class declare as follows:
template <class T>
class MyTemplatedClass
{
T mydata;
public:
int myfun(int x);
// ...
};
and declare member functions as follows:
template <class T>
int MyTemplatedClass<T>::myfun(int x) { ... }
- Use
template<class T>at start of class prototype and before every function implementation for the class - Can use
Tas type in class member definitions - Use
MyTemplatedClass<T>in function implementation as whole class name - Use
MyTemplatedClass<type>with realtypeor class in order to create an object
In C++, the class definition and the function implementations must be in the same file! You can do this in either a .h, .cpp, or even .hpp file. That file must then be compiled with any other code using the templated class. Another approach is to put the template implementations in a separate file (*.inc) and then #include that at the end of your .h template header file.
Using multiple template parameters
template <class T1, class T2>
class C2 {
public:
C2() { };
C2(T1 a, T2 b) { thing1=a; thing2=b; };
private:
T1 thing1;
T2 thing2;
};
//usage
C2<int, float> a1; // nothing is initialized
C2<double, int> a2(2.3, 4);
Templates also support data parameters too, not just types.
template <int Maxsize> // Maxsize is int template parameter
class Mstring {
public:
Mstring() { str[0] = '\0'; };
private:
char str[Maxsize];
};
// usage
Mstring<20> name; // copy of Mstring with 20 replacing Maxsize
Mstring<10> city; // copy of Mstring with 10 replacing Maxsize
int i=5;
// Mstring<i> zip; // ILLEGAL - must use constant!!
const int max=5;
Mstring<max> zip; // LEGAL, max is const-declared
The example above is not a practical use of templates however. It wastes space because it makes a copy for each size. Also because they are different types technically, we can’t compare name and city variables to each other.