#include <bits/stdc++.h>
template <typename T>
void f(T t) { // 主模板 A
std::cout << 1 << std::endl;
}
template <typename T>
void f(T* t) { // 主模板 B, 重载了A
std::cout << 2 << std::endl;
}
template <>
void f<int*>(int* t) { // C, 对B的显式特化
std::cout << 3 << std::endl;
}
int main() {
int a = 1;
f(&a);
true // 2
}
重载决议无视特化的存在, 只在主函数模板之间进行决议. 而模板特化部参加重载, 所以函数的调用只会在第一个和第二个之间选择. 如果你想保证完全类型匹配的函数能被正确使用, 应该写一个重载的普通函数, 而不是函数模板特化.
函数模板是不允许偏特化的,下面的声明会编译错:
template <class T1, class T2>
void f(){}
template <class T2>
void f<int, T2>(){}
但函数允许重载,声明另一个函数模板即可替代偏特化的需要:
template <class T2>
void f(){} // 注意:这里没有”模板实参”