模板的特化:函数模板的特化和类模板的特化
当函数模板或者类模板需要对一些特殊的类型做特殊处理的时候,需要用到c++中模板的特化机制。
比如如下代码,模板ret_max中两个参数t1和t2,可以是多个类型,int,double,。如果需要对特殊的类型如下面代码的char *类型,做特殊的处理,就是里面实现的功能不一样。就可以使用如下的方法。
#if 1
template <class T>
bool ret_max(T t1, T t2)
{
cout << "the fun:ret_max(T t1, T t2) :";
return (t1 > t2) ? t1 : t2;
}
#endif
template <> bool ret_max<char *>(char *str1, char *str2)
{
cout << "the fun:ret_max(char *str1, char* str2) :";
return strcmp(str1, str2) == 0;
}
类模板的特化也是一样,具体的格式如下:
// (1)
template <class A, class B, class C>
class T {};
//(2)
template <>
class T<float, long, int>{};
//(3)
template <class B, class C>
class T<int, B, C>{};
如果编译器遇到是T <float, long, int>模板的实例化请求,那么就是特例化后的版本,即:(2)。当编译器遇到T <int, long, int>,T <int, double, long>,也就是说只要第一个模板的参数是int,实例化请求就使用(3)。其他的情况就是使用(1)。
还有一种情况就是如果参数有某一个特殊的类型,也可以实例化,如下:
//(1)
template <class T>
class X{};
//(2)
template <class T>
class X<T*>{};
当编译器遇到X<int>或者X<double>的时候使用模板(1),如果遇到X<int*>或者X<double*>时使用模板(2)。也有可能是如下的形式:
//(1)
template <typename A, typename B>
class D{};
//(2)
template <typename A>
class D<A*, int>
当编译器遇到D<int*,int>或者是D<char*,int>的时候就会使用模板(2),其他的情况使用模板(1).
一个类模板的特化简单示例如下:
template <class ARG>
class compare{
public:
bool is_equal(ARG arg1, ARG arg2)
{
cout << "the fun:is_equal(ARG arg1, ARG arg2) :";
return arg1 == arg2;
}
};
template <>
class compare<char*>{
public:
bool is_equal(char* arg1, char* arg2)
{
cout << "the fun:is_equal(char* arg1, char* arg2):";
return strcmp(arg1, arg2)==0;
}
};
完整的测试代码如下:
#include "stdafx.h"
#include <iostream>
using namespace std;
#if 1
template <class T>
T ret_max(T t1, T t2)
{
cout << "the fun:ret_max(T t1, T t2) :";
return (t1 > t2) ? t1 : t2;
}
#endif
template <> bool ret_max<char *>(char *str1, char *str2)
{
cout << "the fun:ret_max(char *str1, char* str2) :";
return strcmp(str1, str2) == 0;
}
template <class ARG>
class compare{
public:
bool is_equal(ARG arg1, ARG arg2)
{
cout << "the fun:is_equal(ARG arg1, ARG arg2) :";
return arg1 == arg2;
}
};
template <>
class compare<char*>{
public:
bool is_equal(char* arg1, char* arg2)
{
cout << "the fun:is_equal(char* arg1, char* arg2):";
return strcmp(arg1, arg2)==0;
}
};
int main()
{
char str1[] = "this2";
char str2[] = "this2rrrr";
#if 1
cout << "***********function specialization:******************" << endl;
cout << "max value:" << ret_max(1, 2) << endl;
cout << "max value:" << ret_max(1.1f, 2.6f) << endl;
cout << "max value:" << ret_max(1.123l, 2.3456l) << endl;
cout << "max value:" << ret_max('b', 'd') << endl;
cout << "max value:" << ret_max<int>(3, 2.4) << endl;
cout << " str1 and str2 are equal:" << ret_max(str1, str2) << endl;
#endif
cout << "************class specialization:********************" << endl;
compare<int> val1;
compare<char *> val2;
cout << "call1: "<<val1.is_equal(1, 2) << endl;
cout << "call2: " << val1.is_equal(3, 3) << endl;
cout << "call3: " << val2.is_equal(str1, str2) << endl;
//cout << "call4: " << val2.is_equal(str1, str1) << endl;
return 0;
}
测试结果:
***********function specialization:******************
the fun:ret_max(T t1, T t2) :max value:1
the fun:ret_max(T t1, T t2) :max value:1
the fun:ret_max(T t1, T t2) :max value:1
the fun:ret_max(T t1, T t2) :max value:1
the fun:ret_max(char *str1, char* str2) : str1 and str2 are equal:1
the fun:ret_max(char *str1, char* str2) : str1 and str3 are equal:0
************class specialization:********************
the fun:is_equal(ARG arg1, ARG arg2) :call1: 0
the fun:is_equal(ARG arg1, ARG arg2) :call2: 1
the fun:is_equal(char* arg1, char* arg2):call3: 1
请按任意键继续. . .