Step 7 of 8
Template specialization
Sometimes one particular type needs different behavior from the general template. A full specialization provides a replacement definition for exactly that type, and the compiler picks the most specific match.
#include <iostream>
#include <string>
template <typename T>
struct Unit {
static std::string symbol() { return ""; }
};
template <>
struct Unit<double> {
static std::string symbol() { return " m"; }
};
template <>
struct Unit<std::string> {
static std::string symbol() { return " (label)"; }
};
template <typename T>
void print_value(const T& v) {
std::cout << v << Unit<T>::symbol() << "\n";
}
int main() {
print_value(3.5);
print_value(std::string("door"));
print_value(7);
}
3.5 m
door (label)
7
How it works
- The general template is written first. Every specialization comes after it.
template <>with empty brackets means "all the parameters are already filled in". Thenstruct Unit<double>names the exact type being specialized.- A specialization is a completely separate definition. It doesn't inherit anything from the general version, so you must write every member you need.
print_valueusesUnit<T>::symbol(). Forintthere's no specialization, so the general version is used and returns an empty string.staticmember functions are called on the class itself, with::, no object needed.
Where you'll see this
This is how the standard library lets you plug your own types into its templates. For example, to use your own struct as a key in std::unordered_map, you specialize std::hash<YourType>.
Your turn: add specializations of TypeName for double ("double"), bool ("bool") and std::string ("string").
Previous: Values as template parameters Next: Challenge: a MinStack<T>