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

让模板类支持可变模板参数(不定个数的参数) (2012-06-30 17:03)
标签C++  可变参数 分类: C++


原文: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)

在C++语言中,可变参数类模板是一种特殊类型的模板,允许您创建可以在运行时接收任意数量和类型的参数的对象。这种技术通常用于处理需要未知数量输入的函数或构造函数。 可变参数类模板的主要用途包括: ### 实现 `printf` 和 `scanf` 风格的函数 例如,在实现类似 `printf` 或 `scanf` 的自定义函数时,可变参数类模板可以让你编写一次函数就能处理多种数据类型和复杂结构的数据。这使得程序更易于维护、功能更强大,并能适应更多的输入场景。 ### 构造函数参数 在类的构造函数中使用可变参数类模板可以让构造函数接受任意数量和种类的参数。这样可以简化对象创建过程,避免硬编码特定参数列表。 ### 示例:创建一个支持打印各种类型的可变参数类模板 ```cpp template <typename T, typename... Args> class Print { public: void operator()(const T& t, const Args&... args) { std::cout << "Printing type: " << typeid(T).name() << "\n"; if constexpr (std::is_same<T, int>::value) { printInt(t); } else if constexpr (std::is_same<T, double>::value) { printDouble(t); } // 这里可以根据需要添加更多的分支以处理其他类型 //... (Print<Args>()(args)...); // 对其他参数调用相同的行为 } private: template<typename U> static void printInt(U value) { std::cout << value; } template<typename U> static void printDouble(double value) { std::cout << value << ".0"; } // 其他打印特定类型值的私有成员函数可以继续添加 }; ``` 在这个例子中,`Print` 类模板接受一个基础类型 `T` 和一系列后续类型 `Args`,它会根据传入的具体类型调用相应的打印函数。 ### 相关问题: 1. **为什么在C++中使用可变参数模板?** - 它们能够提供高度灵活的功能,如创建通用的日志记录系统或配置文件解析器等。 2. **如何有效地管理可变参数模板实例化?** - 管理大量实例化可能导致内存和性能问题。应尽量减少不必要的实例化并利用预计算等技巧优化性能。 3. **可变参数模板的应用领域是什么?** - 主要应用于需要处理不确定数量参数的情况,如日志记录、配置加载、命令行参数解析等领域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值