您的位置:首页 > 其它

让模板类支持可变模板参数

2009-10-22 22:55 218 查看
让模板类支持可变模板参数
现如今才正真发现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;
}
我们很容易地就实现了不定参数的模板类。呵呵
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struct c