[开源世界]如何让C++的模板类支持多参数但同名?

在C++中,根据函数参数个数的不同区分函数重载再常见不过了。也就是说,向下面这样的函数重载在C++中是合法的。

int max(int a, int b) { return a>b?a:b; }

int max(int a, int b, int c) { return max(a,b)>max(b,c)?max(a,b):max(b,c); }

当我们把这条经验扩展到C++的模板系统时,它仍然是有效的。

template<typename _T> void debug(_T a, std::string b) { cout<<a<<b; }

template<typename _T, typename _T1> void debug(_T a, _T1 b, std::string c) { cout<<a<<b<<c; }

但是当我们进一步将这条经验试图扩展到C++的类模板时,它失效了。也就是说,像下面这样的模板类在C++中是非法的(VC++编译器报告Debug模板参数太多)。

template<typename _T> struct Debug {

_T _a;

Debug(_T a) : _a(a) {}

void debug(std::string s) { cout<<_a<<s; }

};

template<typename _T, typename _T1> struct Debug {

_T _a;

_T1 _b;

Debug(_T a, _T1 b) : _a(a), _b(b) {}

void debug(std::string s) { cout<<_a<<_b<<s; }

};

为了能够让上面的定义在C++中变得合法,我们需要将各自的命名后面加上当前模板参数的个数(这是一般做法)。看起来就像下面这样。

template<typename _T> struct Debug0 {

void debug(_T a,std::string s) { cout<<a<<s; }

};

template<typename _T, typename _T1> struct Debug1 {

void debug(_T a,_T1 b,std::string s) { cout<<a<<b<<s; }

};

然而,我们真的找不到一种方法能够实现上述意图吗?答案可能是否定的。事实上在C++的模板规则中有这样的一条实现:你可以从一堆看起来一样的模板类中选择一个看起来符合的类然后继承它。也就是说,我们能够实现这样的一种形式:

template<typename _T> struct Debug : public one_struct_in_( Debug0, Debug1) {};

它的实现就需要本文将要介绍的模板参数系统。我认为这种技术的核心在于将函数指针的各部分的类型分开。也就是说,对一个模板类输入如下参数时,

Debug<void(int,int)>

能够获得如下的事实成立,

Debug<void(int,int)> : Debug1<int,int>

或者,对一个模板类输入如下参数时,

Debug<void(int)>

能够获得如下的事实成立,

Debug<void(int)> : Debug0<int>

客户端可以实现像下面这样的使用体验,

Debug<void(int)> a;

a.debug(3,"0");

Debug<void(int,string)> b;

b.debug(3, "4","0");

如果读者对这种技术感兴趣的话,请移步下面的网址下载示例程序。

https://tmplargs.codeplex.com/

顺便说一句,这个技术是完全开源的。

转载于:https://my.oschina.net/lvan100/blog/285627

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值