模板函数重载
例子:
template<typename T> //(a):主模板
void f(T t)
{
cout << "template 1/n";
}
int main(int argc, char *argv[])
{
int *p = new int(2);
f(p);
f(*p);
system("PAUSE");
return 0;
}
如果只有上面这一个函数模板,
main中的两个调用自然都匹配这个模板。如果增加一个模板:
template<typename T> //(b):主模板,重载了
(a)
void f(T *t)
{
cout << "template 2/n";
}
那么
f(p)调用(
b),
f(*p)调用(
a)。如果再增加一个特化模板:
template<> void f<int *>(int *t) //(c):
(a)的特化
{
cout << "template 3/n";
}
出乎意料,
f(p)还是调用
(b),
f(*p)还是调用
(a)。这是因为重载决议时只考虑主模板。
如果将
(b)也特化:
template<> void f<int>(int *t) //(d):
(b)的特化
{
cout << "template 5/n";
}
这时
f(p)调用的时
(d),
f(*p)调用的是
(a)。
如果提供一个普通函数:
void f(int *p) //(e):普通函数
{
cout << "no template/n";
}
此时
f(p)调用
(e)。
准则:函数模板特化并不参与重载决议。只有在某个主模板被重载决议选中的前提下,其特化版本才有可能被使用。而且,编译器在选择主模板的时候并不关心它是否有某个特化版本。
准则:如果一个普通的非模板函数跟一个函数模板在重载解析的参数匹配中表现一样好的话,编译器会选择普通函数。
更多内容请参考《
Exceptional C++ Style》第
7条。