Template Specialization
Sometimes the generic version of a template isn't the right implementation for every type. A container template might store bool values one bit at a time instead of one byte at a time for efficiency, or a generic printing function might need different formatting for char* strings than for numbers. Template specialization lets you provide a completely different implementation for one specific type (or family of types) while keeping the generic template for everything else.
Full specialization
A full specialization replaces the entire template body for one exact type. The syntax starts with template<> (empty angle brackets, meaning “no template parameters left”) followed by the class name with the specific type filled in.
box_specialization.cpp
CPP
#include <iostream>
#include <string>
// Generic version — works for any type.
template <typename T>
class Box {
public:
Box(T value) : value_(value) {}
void describe() const {
std::cout << "Box holding a value: " << value_ << std::endl;
}
private:
T value_;
};
// Full specialization for bool — different behavior for this one type.
template <>
class Box<bool> {
public:
Box(bool value) : value_(value) {}
void describe() const {
std::cout << "Box holding a boolean: "
<< (value_ ? "true" : "false") << std::endl;
}
private:
bool value_;
};
int main() {
Box<int> intBox(42);
intBox.describe(); // uses the generic template
Box<bool> boolBox(true);
boolBox.describe(); // uses the Box<bool> specialization
return 0;
}Both classes are still called Box, and both are created with the same Box<T>(value) syntax — the compiler automatically picks the specialization when T is exactly bool, and falls back to the generic template for every other type.
Partial specialization
A partial specialization customizes behavior for a family of types rather than one exact type — for example, every pointer type, or every Box<T*>. This is only possible for class templates.
box_partial.cpp
CPP
#include <iostream>
template <typename T>
class Box {
public:
Box(T value) : value_(value) {}
void describe() const {
std::cout << "Box holding a plain value" << std::endl;
}
private:
T value_;
};
// Partial specialization: matches Box<T*> for ANY pointer type T*.
template <typename T>
class Box<T*> {
public:
Box(T* value) : value_(value) {}
void describe() const {
std::cout << "Box holding a pointer, pointee = "
<< *value_ << std::endl;
}
private:
T* value_;
};
int main() {
int x = 10;
Box<int> plain(5);
Box<int*> pointerBox(&x);
plain.describe(); // generic template
pointerBox.describe(); // partial specialization for T*
return 0;
}Function templates cannot be partially specialized
This is a common gotcha: C++ only allows partial specialization for class templates. Function templates only support full specialization (and even then, overloading is usually the better tool for functions — see the Function Templates page). If you find yourself wanting to partially specialize a function template, the idiomatic workaround is to wrap the logic in a class template (or a helper struct) and partially specialize that instead, or to rely on plain function overloading.
When to reach for specialization
The generic implementation is correct for a type but inefficient (classic example:
std::vector<bool>uses a packed bit representation).The generic implementation doesn't make sense for a type at all (e.g., a generic "print" template needs special handling for
char*C-strings vs. treating them as raw addresses).You want to intercept exactly one type (full specialization) or a pattern of types like all pointers, all arrays, or all
std::vector<T>(partial specialization).