Template Specialization in C++
Introduction
Templates in C++ allow you to write generic and reusable code. However, there are times when you need to handle specific types differently. Template specialization is a feature of C++ that allows you to provide custom implementations for specific template arguments.
Basic Template Example
Let's start with a simple example of a template function:
template <typename T>
void print(T value) {
std::cout << "Value: " << value << std::endl;
}
You can use this template function with different types:
int main() {
print(10); // Works with int
print(5.5); // Works with double
print("Hello"); // Works with const char*
return 0;
}
Need for Template Specialization
Sometimes, the default template implementation is not suitable for all types. For example, you might want to handle const char*
differently than other types. This is where template specialization comes in.
Template Specialization Syntax
To specialize a template for a specific type, you need to provide a specialization of the template. Here's the syntax:
template <>
void print<const char*>(const char* value) {
std::cout << "String: " << value << std::endl;
}
Full Example with Specialization
Let's put it all together and create a full example with template specialization:
#include <iostream>
template <typename T>
void print(T value) {
std::cout << "Value: " << value << std::endl;
}
template <>
void print<const char*>(const char* value) {
std::cout << "String: " << value << std::endl;
}
int main() {
print(10); // Uses the general template
print(5.5); // Uses the general template
print("Hello"); // Uses the specialized template
return 0;
}
Output:
Value: 10
Value: 5.5
String: Hello
Class Template Specialization
Just like function templates, you can also specialize class templates. Here's an example:
template <typename T>
class Storage {
public:
Storage(T value) : value(value) {}
void print() {
std::cout << "Value: " << value << std::endl;
}
private:
T value;
};
template <>
class Storage<const char*> {
public:
Storage(const char* value) : value(value) {}
void print() {
std::cout << "String: " << value << std::endl;
}
private:
const char* value;
};
Usage of the specialized class:
int main() {
Storage<int> intStorage(10);
Storage<const char*> stringStorage("Hello");
intStorage.print(); // Uses the general template
stringStorage.print(); // Uses the specialized template
return 0;
}
Output:
Value: 10
String: Hello
Partial Specialization
C++ also supports partial specialization of class templates. However, partial specialization is not allowed for function templates. Here's an example of partial specialization:
template <typename T, typename U>
class Pair {
public:
Pair(T first, U second) : first(first), second(second) {}
void print() {
std::cout << "Pair: " << first << ", " << second << std::endl;
}
private:
T first;
U second;
};
template <typename T>
class Pair<T, T> {
public:
Pair(T first, T second) : first(first), second(second) {}
void print() {
std::cout << "Equal Pair: " << first << ", " << second << std::endl;
}
private:
T first;
T second;
};
Usage of the partially specialized class:
int main() {
Pair<int, double> mixedPair(10, 5.5);
Pair<int, int> equalPair(10, 10);
mixedPair.print(); // Uses the general template
equalPair.print(); // Uses the partially specialized template
return 0;
}
Output:
Pair: 10, 5.5
Equal Pair: 10, 10
Conclusion
Template specialization in C++ is a powerful feature that allows you to provide custom implementations for specific types. This tutorial covered the basics of template specialization, including function and class template specialization, as well as partial specialization. With these tools, you can write more flexible and reusable code.