模板技术之编译期识别类型转换和继承性

问题

如何识别两个模板参数T和U是否有继承关系?

原理

sizeof的威力

sizeof可以用于任何表达式,在编译期评估表达式类型的大小。因此,sizeof可以感知重载、模板实例化、转换规则,或任何可发生于C++表达式身上的机制。

识别类型转换能力机制

运用sizeof和重载函数
1、函数重载提供选择分支
提供两个重载函数:一个接受目标类型U——1号函数,另一个接受其它任何类型——2号函数。用户用类型T来调用这些函数,用户想知道T是否可以转换成U。如果1号函数被调用,说明T可以转换成U,否则无法转换成U。
2、sizeof识别那个分支被调用
对上述两个重载函数安排大小不同的返回型别,用sizeof来区分其大小,通过大小就可以识别出那个函数被调用。

实现

1、建立两个返回值类型

using Small = char;
struct Big { char dummy[2]; };

2、声明两个重载函数

Small Test(U);
Big Test(...); //接受任意类型参数

3、sizeof识别

const bool convExists = sizeof(Test(T())) == sizeof(Small);

这里可能存在无法覆盖的点:
T没有无参构造函数或无参构造函数非public,则T()不合法。
改进:"稻草人函数"返回类型T

T makeT();
const bool convExists = sizeof(Test(makeT()) == sizeof(Small);

最终产物:

template<typename T, typename U>
struct Conversion
{
public:
	enum 
	{ 
		exists = sizeof(test(makeT())) == sizeof(Small)
	};
	
	enum 
	{ 
		exists2way = exists and Conversion<U, T>::exists  //双向转换
	};
	
	enum { sameType = false } ;

	
private:
	using Small = char;
	class Big{ char dummy[2]; };
	static Small test(U) ;
	static Big test(...);
	static T makeT( ) ;
} ;

偏特化实现识别相同类型:

template<typename T>
struct Conversion<T, T>
{
	enum 
	{ 
		exists = true,
		exists2way = true, 
		samerype = true
	};
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值