Skip to content

87 Advanced The Hundred

The Specialization Nobody Called

you hand-wrote the int* case; now watch who answers

#include <iostream>

template <class T> void dump(T) { std::cout << "generic\n"; }

template <class T> void dump(T*) { std::cout << "pointer\n"; }

template <> void dump<int*>(int* p) { std::cout << "int pointer -> " << *p << "\n"; }

int main() {
    int n = 42;
    dump(n);
    dump(&n);
}

Run it. What does it print?

Answer
generic
pointer

The specialization written for exactly this call never runs.

Why

An explicit specialization is not an overload, and it does not take part in overload resolution: the compiler first ranks the base templates, and only then asks the winner whether it has a specialization for these arguments. For dump(&n) both templates match perfectly — T = int* for the first, T = int for the second — and partial ordering declares the T* version more specialized, so template #2 wins and prints pointer. But template <> void dump<int*>(int*) specialized template #1: for #2, dump<int*> would mean void dump(int**), which does not fit that parameter at all. So the specialization is attached to the template that lost, and never gets a vote — it is perfectly healthy, just never consulted, and dump<int*>(&n) still reaches it by name. Moving the specialization above the T* overload changes nothing; writing it instead as template <> void dump<int>(int*) does — that attaches to the winning template, and fires. GCC 11 says nothing about any of this, even with -Wall -Wextra -pedantic.

The fix

Prefer a plain function overload — overloads are what resolution actually ranks, and an exact non-template match beats every template:

void dump(int* p) { std::cout << "int pointer -> " << *p << "\n"; }

If you genuinely need the specialization machinery, specialize a class template and let one thin function forward to it — a class template has no overload set to lose in, so its specializations are matched against the arguments directly.

Takeaway: overload resolution chooses the template first; only the winner's specializations ever get a say.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry