利用模板别名using实现TypeList

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

实现TypeList

template<typename T, typename U>
struct TypeList
{
	using Head = T;
	using Tail = U;
};

背后的机制

template参数可以是任何型别,包含该template的其他具现体。

作用

TypeList 内部没有任何数值:它们的实体是空的,不含任何状态,也未定义任何函数。执行期间t不带任何数值。它存在的理由只是为了携带型别信息。

使用

例子:
using CharList = TypeList<char, TypeList<signed char, char>>

优化

存在的问题1:
上述实现无法表达出拥有0个或1个类型的TypeList。

优化1: 增加结束标识
引入模板技术: NullType

struct NullType;   // 无任何实现的类型,只是声明

就像C字符串一样,制定习惯:每个TypeList都必须以Nu11Type 结尾,将NullType当作其结束符。
实现持有一个类型的TypeList

template<typename T>
using OneTypeList = TypeList<T, NullType>;

存在的问题2:
利用原生的TypeList定义类型数组:

using SignedIntegrals = TypeList<signed char, 
												TypeList<short, 
													TypeList<int, 
														TypeList<long, NullType>>>>;

可以看出,用户使用起来太不友好,容易出错。
优化2: 可用性的线性化封装
引用的技术: C++11的using模板别名特性。

template<typename T>
using TypeList1 = TypeList<T, NullType>;

template<typename T1, typename T2>
using TypeList2 = TypeList<T1, TypeList1<T2>>;

template<typename T1, typename T2, typename T3>
using TypeList3 = TypeList<T1, TypeList2<T2, T3>>;
// ...
// 以下是伪代码
template<typename T1, ..., typename T50>
using TypeList50 = TypeList<T1, TypeList49<T2, ..., T50>>;

优点: 扩展性和可读性好
每个模板别名类使用前一个模板别名类,这让程序库使用者可以轻易扩充上限。
重新实现上述例子:

using SignedIntegrals = TypeList4<signed char, short, int, long>;

可以看出,更加的简洁直白,且用户不易写错。
问题3: 访问类型元素不便利

// 如果我们访问SignedIntegrals的最后一个类型
SignedIntegrals::Tail::Tail::Tail;

这样不够清晰易懂,写和理解都费事。
优化3: 模仿list类型,从长度入手。
1. 实现长度计算
背后的技术:模板类的偏特化+编译期整数计算

template<typename TypeList>
struct Length;

template<>
struct Length<NullType>
{
	enum{ value = 0 };
};

template<typename T, typename U>
struct Length<TypeList<T, U>>
{
	enum { value = 1 + Length<U>::value };
};

2. 索引式访问
背后的技术:模板偏特化+编译期递归
制定编译期算法:在这里插入图片描述

template<typename TypeList, unsigned index>
struct TypeAt;

template<typename Head, typename Tail>
struct TypeAt<TypeList<Head, Tail>, 0>
{
	using Result = Head;
};

template<typename Head, typename Tail, unsigned i>
struct TypeAt<TypeList<Head, Tail>, i>
{
	using Result = typename TypeAt<Tail, i - 1>::Result;
};

再次实现访问的例子

// 获取SignedIntegrals的最后一个类型元素
TypeAt<SignedIntegrals, Length<SignedIntegrals> - 1>::Result;

问题4: 如何获取TypeList中某类型的位置?
优化4:
背后的技术:模板偏特化+编译期递归
制定编译期算法:
在这里插入图片描述

template<typename TypeList, typename T>
struct IndexOf;

template<typename T>
struct IndexOf<NullType, T>
{
	enum { value = -1 };
};

template<typename Tail, typename T>
struct IndexOf<TypeList<T, Tail>, T>
{
	enum { value = 0 };
};

template<typename Head, typename Tail, typename T>
struct IndexOf<TypeList<Head, Tail>, T>
{
private:
	enum { temp = IndexOf<Tail, T>::value };
public:
	enum { value = temp == -1 ? -1 : 1 + temp };
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值