模板的特化:函數模板的特化和類模板的特化
當函數模板或者類模板需要對一些特殊的類型做特殊處理的時候,需要用到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
請按任意鍵繼續. . .