函数模板与函数重载

函数模板与类模板是两大类主要的C++泛型编程的使用方法。

类模板可以进行模板偏特化和全特化,而函数模板只能进行全特化。但是类不同的是,函数还有一个重要的特性就是重载,如果将函数模板与函数重载的问题放在一块的时候,问题就变得比较麻烦了。

看下面的一个例子:

include <iostream>
using  namespace std;
template < class T>
void f(T){
    cout<< " f(T) "<<endl;
}
template < class T>
void f(T*){
    cout<< " f(T*) "<<endl;
}
template<>
void f< int>( int*){
    cout<< " f<int>(int*) "<<endl;
}
template<>
void f< int*>( int*){
    cout<< " f<int*>(int*) "<<endl;
}                              
int main(){
     int *p;
    f(p);
}

运行该程序,会发现运行的结果是:f<int>(int*)

即调用的是第3个函数。
这儿容易让人疑惑的是,为什么不是第4个函数:template<>void f<int*>(int*) 呢?这个是template <class T>void f(T)的模板特化啊。
要理解这个就需要注意一点:带有函数模板的重载进行决议的时候,选择的规则是首先选择最优的普通函数,如果没有适合的普通函数那么就要从模板函数中选择。而进行选择的时候,是决定选择的哪个主模板函数,然后再看这个主模板函数是否存在对应的特化。所以,对于上面的选择,首先是在
template <class T>
void f(T)

template <class T>
void f(T*)
之间进行选择,发现第2个更加合适,这样就确定了主模板函数,然后在查找该主模板函数是否有对应的特化函数,这样正好找到了
template<>
void f<int>(int*)
它是对int的特化,所以最后选择了这个函数。

分开看是如下:

 下面是一个比较全的重载决议的原则:

你可能感兴趣的:(函数)