讓模板類支持可變模板參數



原文: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);
博客推薦文章
  • c++ (2011-10-07 22:48:10)
  • C++ (2012-01-04 15:59:40)
  • c++ (2012-04-14 10:02:01)
  • C++ (2012-05-07 23:22:35)
  • C C++ (2012-03-11 23:37:51)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章