这里说的不是类模板的偏特化,而是偏序函数模板。这个特性在C++标准中并不太明确,各家编译器对它个特性的工作细节可能会有些差异。
先来看看一个例子:
//filename:function_partial_order.cpp
//wirtten by saturnman
#include<iostream>
usingnamespace std;
//function template partial order feature
template<typename T>
void func1(T t)
{
cout<<"func1 1"<<endl;
}
template<typename T>
void func1(T* t)
{
cout<<"func1 2"<<endl;
}
template<typename T>
void func2(T t)
{
cout<<"func2"<<endl;
}
int main()
{
//test function template partial order
cout<<"test function template partial order."<<endl;
int param1 =10;
int* param2 =NULL;
func1(param1);
func1(param2);
func2(param1);
func2(param2);
return0;
}
上例中对func1有两个重载的模板函数,而对func2只有一个模板函数,我使用一个整数和一个指向整数的指针分别调用func1和func2,注意param1和param2对于func1的第一个定义都是合适的,当然对于func2也是合适的。但是param1对于func1的第二个定义并不合适,param2对于func1的第二个定义是合适的。我们先来查看运行结果
对于第一个函数func1的调用显然是调用了不同的模板函数,这里就有一个谁比谁更特化和谁比谁更一般化的比较规则,更加特化的当然会被优先选择。
这里就有一个所谓的正序规则(Formal Ordering Rules):
1. Replace each template type parameter with
a unique "made up" type.
2. Replace each template template parameter
with a unique "made up" class template.
3. Replace each nontype template parameter
with a unique "made up" value of the appropriate type.
这几句的意思是这样的,编译器片段两个函数模板谁比谁更特化的方法是尝试,编译器自己生成内部类型A,把它分别代入函数func1的模板,比如编译器如下构造{A
a}现在就有了如下两个函数
func1(a); //这个利用第一个模板代入
func1(a*);//这个利用第二个模板代入
现在编译器把这两个反向,把a代码第二个模板,把a*代入第一个模板,显然第一个模板函数是可以接受指针类型的,让T为a*就可以了,但是第二个模板函数不能接收a,因为它的参数必须是一个指针。由此编译器知道第一个函数模板比第二个函数模板更加泛化,也就是说第二个函数模板比第一个函数模板更加特化。因此调用会优先选择更加特化的模板,因此出现上面的结果。
Ref:
《C++ Templates: The Complete Guide》
留言列表