Disclaimer: ChatGPT generated document.
In C++, partial ordering of function templates is the rule the compiler uses to decide which function template is more specialized when multiple templates could match the same call.
Think of it as the compiler asking:
“Given these two templates, which one is more specific for this set of arguments?”
If one template is more specialized, it wins overload resolution.
Consider this:
template<typename T>
void f(T);
template<typename T>
void f(T*);Now call it:
int x;
f(&x);Both templates match:
f(T)→T = int*f(T*)→T = int
Which one should be chosen?
Partial ordering answers this:
👉 f(T*) is more specialized than f(T).
So the call resolves to:
template<typename T>
void f(T*); // chosenGiven two function templates A and B:
- The compiler pretends:
- “Can A be called with B’s parameter types?”
- “Can B be called with A’s parameter types?”
- If A can match B, but B cannot match A, then A is more specialized
- The more specialized template is preferred
This comparison is pairwise, not global.
template<typename T>
void g(T);
template<typename T>
void g(T&);Call:
int x;
g(x);g(T)accepts anythingg(T&)only accepts lvalues
So:
✔ g(T&) is more specialized
❌ g(T) is more general
Result:
template<typename T>
void g(T&); // chosentemplate<typename T, typename U>
void h(T, U);
template<typename T>
void h(T, T);Call:
h(1, 2);Both match, but:
h(T, T)requires both arguments to be same typeh(T, U)allows any two types
So:
✔ h(T, T) is more specialized
👉 it is selected
template<typename T>
void p(T*);
template<typename T>
void p(const T*);Call:
const int x = 0;
p(&x);Which wins?
p(T*)→T = const intp(const T*)→T = int
const T* is more constrained, so:
template<typename T>
void p(const T*); // chosenImportant distinction:
- Overload resolution decides between:
- non-template functions
- template functions
- function templates vs non-templates
- Partial ordering is only used when comparing function templates against each other
Example:
void f(int); // non-template
template<typename T>
void f(T);Call:
f(10);➡️ Non-template wins before partial ordering even applies.
Partial ordering is used for:
- Function templates
- Member function templates
- Overloaded operator templates
- Deduction guides (similar logic)
It does not apply to:
- Class templates (they use specialization rules instead)
- Variable templates
template<typename T>
void q(T, int);
template<typename T>
void q(int, T);
q(1, 1); // ❌ ambiguousNeither is more specialized — compilation error.
template<typename T>
void r(T);
template<typename T>
void r(auto);Both may appear equivalent — can easily lead to ambiguity.
You can remember it like this:
The template that accepts fewer kinds of arguments is more specialized.
Or:
More constraints = higher priority
Partial ordering of function templates is the C++ mechanism that ranks competing function templates by how specialized they are. When multiple templates can match a call, the compiler compares them pairwise and prefers the one that is more constrained and matches a narrower set of arguments. This prevents ambiguity and allows you to write clean overload sets using templates.
