原文:http://blog.csdn.net/bluedog/article/details/4715542
現如今才正真發現c++模板的強大,模板的強大在於不需要使用RTTI機制可以傳遞參數的類型信息,不過也有其遺憾的地方,就是對於引用和複製,模板並無法區分。例如
template<typename T>
struct Test
{
typedef T Type;
static void PrintTemplateTypeName()
{
cout << typeid(Type).name() <<endl;
}
};
如果我們分別用
第一組 Test<int>,Test<int&>,Test<const int&>其結果是相同的,總是輸出 int
第二組 Test<int*>,Test<int* const> 總是輸出 int *
第三組 Test<const int*>,Test<const int* const> 總是輸出 int const *
此處如果對於 const int * 與 int * const還不瞭解的朋友可以這樣來看
(a)const int * <==> (const int)* 即指向常量int值的指針,它也可以表述爲 int const *;
(b)int * const <==> (int *) const 即是一個int型指針,不過這個指針不能改變,即不可以做 ++ -- 等操作。
所以很多在寫常量字符串指針時寫成
const char * str = "Hellow,C++";
這種寫法應該說是不完善的,正確的寫法應該如下
const char * const str = "Hellow ,C++!";
講了這麼多,其實跟我們今天所要講的東東關係不是很大,我們只要瞭解到模板不能傳遞模板參數類型的引用和const修鉓定義。下面走入正題
爲什麼我們需要模板類支持可變模板參數?
我在寫c++事件支持時,需要使用下面一種語法,事件需要一個委託定義。但是由於用戶的委託類型是可變的,而且參數也是不一定的,假如這個委託模板類的名字叫delegate,我們好象不能同時寫出下面這幾種東東出來
delegate<void,void> ClickHandler;
delegate<void,int,int> DrawHandler;
delegate<int,CDC*, CPoint,CString> DrawTextHandler;
因爲類並不支持重載。事實上網上流傳的FastDelegate也是使用了FastDelegate0,FastDelegate1這樣的東東來區分不同數量的模板參數。
模板總是讓我們不斷髮現它的強大。忽然我開悟了,完全可以讓模板類支持不同數量的參數。下面給出我的代碼,有代碼有真相!
template<typename T>
struct is_non_template_param
{
enum { have_template_param =1 };
};
template<>
struct is_non_template_param<void>
{
enum { have_template_param =0 };
};
template<typename T1,typename T2,typename T3,typename T4,typename T5>
struct template_params
{
enum { count = is_non_template_param<T1>::have_template_param +
is_non_template_param<T2>::have_template_param +
is_non_template_param<T3>::have_template_param +
is_non_template_param<T4>::have_template_param +
is_non_template_param<T5>::have_template_param };
};
template<typename T1 = void,
typename T2 = void,
typename T3 = void,
typename T4 = void,
typename T5 = void>
struct Delegate
{
enum{ ParamsCount = template_params<T1,T2,T3,T4,T5>::count };
int GetParamsCount()
{
return ParamsCount;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Delegate<int,double,char> d1;
Delegate<int,int*,char*,int> d2;
Delegate<void> d3;
cout <<"d1 params count =" << d1.GetParamsCount()<<endl;
cout <<"d2 params count =" << d2.GetParamsCount()<<endl;
cout <<"d3 params count =" << d3.GetParamsCount()<<endl;
return 0;
}
我們很容易地就實現了不定參數的模板類。呵呵
(function(w, d, g, J) { var e = J.stringify || J.encode; d[g] = d[g] || {}; d[g]['showValidImages'] = d[g]['showValidImages'] || function() { w.postMessage(e({'msg': {'g': g, 'm':'s'}}), location.href); } })(window, document, '__huaban', JSON);