模板技术之型别转换实现Tag

128 篇文章 0 订阅
65 篇文章 0 订阅

型别映射

问题:C++中不存在函数模板偏特化
有时我们期待型别转换,输入一种数据类型,输出另一种数据类型,如下代码所示。

template<typename T, typename U>
T* Create(const U& arg)
{
	return new T(arg);
}

有时,系统中存在旧代码,如Widget,需要两个参数才能构建出对象,第二个参数固定为-1,它的派生类则没有这种问题。
由于函数模板特性限制,我们如下代码不符合规则。

//非法代码
template<typename U>
Widget* Create<Widget, U>(const U& arg)
(
	return new Widget(arg, -1);
}

为实现上面的转化功能,我们可以利用函数的重载机制,于是,可以采用如下代码实现。

template<typename T, typename U>
T* Create(const U& arg, T//dummy)
{
	return new T(arg);
}
		  
template<typename U>
Widget* Create(const U& arg, Widget//dummy)
{
	return new Widget(arg, -1);
}

此方案存在一定的风险,当第二个参数是复杂对象时,它的创建会代码很大的额外开销,并且函数根本没有使用到它。
进而,我们期待几乎为0的开销机制。

类型标签(Tag)

C++模板技术,可以实现一种类型转换成另一种类型,这种机制称为类型映射。
针对上述问题,我们可以提供一个类型映射类,如下代码。

template<typename T>
struct Type2Type
{
	using originalType = T;
};

模板可以根据不同的T类型,产生不同的Type2Type<T>类型,该类型中无任何数据成员,对它的创建开销几乎可以忽略不记。
改进上面的代码,实现如下重载函数。

template<typenameT, typename U>
T* Create(const U& arg, Type2Type<T>)
{
	return new T(arg);
}

template<typename U>
Widget* Create(const U& arg, Type2Type<Widget>)
{
	return new Widget(arg, -1);
}

分析上述代码,可以发现Type2Type<T>只是当作一个占位符的作用,就像一个唯一性的标签。这种用法在C++标准库中随处可见,可以称之为类型标签(Tag)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值