Unlike explicit template specialization, which replaces the primary template class with its own complete definitions for a specific data type, partial template specialization allows us to specialize a certain subset of template parameters supported by the primary template class, while the other generic types can be the same as the primary template class.
When partial template specialization is combined with inheritance, it can do more wonders, as shown in the following example:
#include <iostream>
using namespace std;
template <typename T1, typename T2, typename T3>
class MyTemplateClass {
public:
void F1( T1 t1, T2 t2, T3 t3 ) {
cout << "nPrimary Template Class - Function F1 invoked ..." << endl;
cout << "Value of t1 is " << t1 << endl;
cout << "Value of t2 is " << t2 << endl;
cout << "Value of t3 is " << t3 << endl;
}
void F2(T1 t1, T2 t2) {
cout << "nPrimary Tempalte Class - Function F2 invoked ..." << endl;
cout << "Value of t1 is " << t1 << endl;
cout << "Value of t2 is " << 2 * t2 << endl;
}
};
template <typename T1, typename T2, typename T3>
class MyTemplateClass< T1, T2*, T3*> : public MyTemplateClass<T1, T2, T3> {
public:
void F1( T1 t1, T2* t2, T3* t3 ) {
cout << "nPartially Specialized Template Class - Function F1 invoked ..." << endl;
cout << "Value of t1 is " << t1 << endl;
cout << "Value of t2 is " << *t2 << endl;
cout << "Value of t3 is " << *t3 << endl;
}
};
The main.cpp file will have the following content:
#include "partiallyspecialized.h"
int main () {
int x = 10;
int *y = &x;
int *z = &x;
MyTemplateClass<int, int*, int*> obj;
obj.F1(x, y, z);
obj.F2(x, x);
return 0;
}
From the preceding code, you may have noticed that the primary template class name and the partially specialized class name are the same as in the case of full or explicit template class specialization. However, there are some syntactic changes in the template parameter expression. In the case of a complete template class specialization, the template parameter expression will be empty, whereas, in the case of a partially specialized template class, listed appears, as shown in the following:
template <typename T1, typename T2, typename T3>
class MyTemplateClass< T1, T2*, T3*> : public MyTemplateClass<T1, T2, T3> { };
The expression, template<typename T1, typename T2, typename T3>, is the template parameter expression used in the primary class template class, and MyTemplateClass< T1, T2*, T3*> is the partial specialization done by the second class. As you can see, the second class has done some specialization on typename T2 and typename T3, as they are used as pointers in the second class; however, typename T1 is used as is in the second class.
Apart from the facts discussed so far, the second class also inherits the primary template class, which helps the second class reuse the public and protected methods of the primary template class. However, a partial template specialization doesn't stop the specialized class from supporting other functions.
While the F1 function from the primary template class is replaced by the partially specialized template class, it reuses the F2 function from the primary template class via inheritance.
Let's quickly compile the program using the following command:
g++ main.cpp -std=c++17
./a.out
The output of the program is as follows:
Partially Specialized Template Classs - Function F1 invoked ...
Value of t1 is 10
Value of t2 is 10
Value of t3 is 10
Primary Tempalte Class - Function F2 invoked ...
Value of t1 is 10
Value of t2 is 20
I hope that you find the partially specialized template class useful.