C++ Template Specialization - Advanced Topics


C++ template specialization is a powerful feature that allows you to provide customized implementations of templates for specific data types or scenarios. In this guide, we'll explore advanced topics related to template specialization and provide sample code to illustrate their usage.


Function Template Specialization

You can specialize function templates for specific data types. Here's an example of a specialized function template for swapping values of a custom type:


#include <iostream>
using namespace std;
// Primary function template
template <typename T>
void customSwap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
// Specialization for swapping string values
template <>
void customSwap(string& a, string& b) {
string temp = a;
a = "SPECIALIZED_" + b;
b = "SPECIALIZED_" + temp;
}
int main() {
int x = 5, y = 10;
customSwap(x, y);
cout << "Swapped integers: " << x << ", " << y << endl;
string s1 = "Hello", s2 = "World";
customSwap(s1, s2);
cout << "Swapped strings: " << s1 << ", " << s2 << endl;
return 0;
}

In this example, we have a primary function template `customSwap` for swapping values and a specialization for swapping string values with a custom prefix.


Class Template Specialization

You can also specialize class templates for specific data types. Here's an example of a specialized class template for working with complex numbers:


#include <iostream>
#include <complex>
using namespace std;
// Primary template
template <typename T>
class ComplexNumber {
public:
ComplexNumber(T real, T imag) : realPart(real), imagPart(imag) {}
void display() {
cout << "Real: " << realPart << ", Imaginary: " << imagPart << endl;
}
private:
T realPart;
T imagPart;
};
// Specialization for complex numbers with integer real and imaginary parts
template <>
class ComplexNumber<int> {
public:
ComplexNumber(int real, int imag) : realPart(real), imagPart(imag) {}
void display() {
cout << "Integer Complex: Real: " << realPart << ", Imaginary: " << imagPart << endl;
}
private:
int realPart;
int imagPart;
};
int main() {
ComplexNumber<double> complex1(3.0, 4.0);
ComplexNumber<int> complex2(1, 2);
cout << "Complex Number 1: ";
complex1.display();
cout << "Complex Number 2: ";
complex2.display();
return 0;
}

In this example, we define a primary class template `ComplexNumber` for working with complex numbers and a specialization for complex numbers with integer real and imaginary parts.


Template Specialization for Enums

You can specialize templates for enum values. Here's an example of a specialized template for printing days of the week:


#include <iostream>
using namespace std;
enum class DayOfWeek { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
// Primary template
template <DayOfWeek D>
void printDay() {
cout << "Unknown Day" << endl;
}
// Specializations for specific days of the week
template <>
void printDay<DayOfWeek::Sunday>() {
cout << "Sunday" << endl;
}
template <>
void printDay<DayOfWeek::Monday>() {
cout << "Monday" << endl;
}
int main() {
printDay<DayOfWeek::Sunday>(); // Calls the specialized version
printDay<DayOfWeek::Monday>(); // Calls the specialized version
printDay<DayOfWeek::Wednesday>(); // Calls the primary template
return 0;
}

In this example, we specialize the template `printDay` for specific days of the week while providing a default implementation for an unknown day.


Conclusion

C++ template specialization allows you to tailor your generic code to specific data types or scenarios. You can specialize both function and class templates, as well as templates for enums, to create customized implementations. Understanding these advanced topics in template specialization can help you write more versatile and efficient C++ code.