您的位置:首页 > 编程语言 > C语言/C++

重学C++ (十二) 模板特化和偏特化

2016-03-03 22:54 483 查看

一、模板的定义

1.类模板

[code]template <class T>
class compare
{
public:
    bool IsEqual(T t1, T t2)
    {
        return t1 == t2;
    }
};

int main()
{
    char str1[] = "Hello";
    char str2[] = "Hello";
    compare<int> c1;
    compare<char *> c2;   
    cout << c1.IsEqual(1, 1) << endl;        //比较两个int类型的参数
    cout << c2.IsEqual(str1, str2) << endl;   //比较两个char *类型的参数
    return 0;
}


2.函数模板

[code]bool IsEqual(T t1, T t2)
{
    return t1 == t2;
}

int main()
{
    char str1[] = "Hello";
    char str2[] = "Hello";
    cout << IsEqual(1, 1) << endl;
    cout << IsEqual(str1, str2) << endl;
    return 0;
}


二、模板特化

上述代码中,比较字符串是否相等,由于传入的参数是char *类型的,IsEqual函数模板只是简单的比较传入参数的值,即两个指针是否相等,因此结果为false。显然,这与我们的初衷不符。因此,上述模板需要对char *类型进行特别处理,即特化。

1.类模板特化

[code]template <> //告诉编译器这是一个特化的模板
class compare<char *> //特化(char*)
{
public:
    bool IsEqual(char* t1, char* t2)
    {
        return strcmp(t1, t2) == 0;         //使用strcmp比较字符串
    }
};


注意,如果是在类特化外部定义成员时,成员之前不能加template<>标记。

另外,我们可以只特化成员而不特化类,比如vector中,我们可以只特化push_back操作:

[code]template<>
void vector<const char *>::push_back(const char *const &val)
{
    //...
}


类类型vector

2.函数模板特化

[code]template <> 
bool IsEqual(char* t1, char* t2) //函数模板特化
{
    return strcmp(t1, t2) == 0;
}


三、模板偏特化

1.类模板的偏特化

当有多个模板形参时,我们可以只特化一部分形参而不是全部。

c++标准库中的类vector的定义就是一个例子:

[code]template <class T, class Allocator>
class vector { // … // };

template <class Allocator>
class vector<bool, Allocator> { //…//};


上述例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。

2.函数模板的“偏特化”

严格来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。

[code]template <class T> void f(T);  (a)


根据重载规则,对(a)进行重载

[code]template < class T> void f(T*);  (b)


如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。

四、模板特化时的匹配

1.类模板的匹配

最优化的优于次特化的,即模板参数最精确匹配的具有最高的优先权

例子:

[code]template <class T> class vector{//…//}; // (a)  普通型
template <class T> class vector<T*>{//…//};  // (b) 对指针类型特化
template <>   class vector <void*>{//…//};  // (c) 对void*进行特化


每个类型都可以用作普通型(a)的参数,但只有指针类型才能用作(b)的参数,而只有void*才能作为(c)的参数

2.函数模板的匹配

非模板函数具有最高的优先权。如果不存在匹配的非模板函数的话,那么最匹配的和最特化的函数具有高优先权

例子:

[code]template <class T> void f(T);  // (d)
template <class T> void f(int, T, double); // (e)
template <class T> void f(T*);  // (f)
template <> void f<int> (int) ; // (g)
void f(double);  // (h)
bool b;
int i;
double d;
f(b); // 以 T = bool 调用 (d)
f(i,42,d) // 以 T = int 调用(e)
f(&i) ; // 以 T = int* 调用(f)
f(d);  //  调用(g)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: