c++泛型编程之Typelists

Typelists是一个用来操作一大群型别的C++工具。就像lists对数值提供各种基本操作一样,typelists对型别也提供相同的操作。

比如有时候必须对某些型别重复撰写相同的代码,但是template又帮不上忙。假设需要实作一个Abstract Factory,像如下这样:

cpp 复制代码
class AbstractFactory {
public:
	virtual Window* createWindow() = 0;
	virtual Button* createButton() = 0;
	virtual ScrollBar* createScrollBar() = 0;
	// ......
};

如果想将以上AbstractFactory的概念特化,并纳入程序库中,你必须让使用者得以产生针对任意性别的工厂,但是template无法支持这一特性。此时Typelists可以帮助AbstractFactory泛化成功。

Typelists的定义

Typelists是一个编译期的类型链表,该功能在c++11/17中已经有std::tuple支持,std::tuple的底层实现就是TypeList。定义如下:

cpp 复制代码
template<typename T, typename U>
struct TypeList {
	typedef T Head;
	typedef U Tail;
}

说明:

T:当前节点存储的类型

U:当前节点的后继节点。该节点有两种情况,一种情况是TypeList<...>类型(链表的下一个节点),另一个情况是标记一种类型,即代表链表的尾部。

typedef T Head; 代表当前节点存储大的类型;

typedef U Tail; 代表下一节点,即列表的剩余部分。

比如定义一个嵌套实例化的链表:typedef TypeList<int, TypeList<double, TypeList<std::string, void>>> MyTyppes;中,Head代表int,Tail代表TypeList<double, TypeList<std::string, void>>

按索引访问

按索引访问定义如下:

cpp 复制代码
template<typename TList, unsigned int index>
struct TypeAt;

template<class Head, class Tail>
struct TypeAt<TypeList<Head, Tail>, 0> {
	typedef Head Result;
};

template<class Head, class Tail, unsigned int index>
struct TypeAt<TypeList<Head, Tail>, index> {
	typedef typename TypeAt<Tail, index-1>::Result Result;
}

说明:

首先声明主模板,再通过模板的特化实现具体逻辑。

实现模版的全特化作为递归的终止条件,即当index=0时,获得的类型为Head存储的对应类型;

实现模板的偏特化作为递归的递归逻辑,进行模板的逻辑推倒,即跳过列表的头部元素,去剩余的类型中找第index-1个类型,依次类推,直到index变成0.

typename是一种语法要求,声明访问的是类型。访问嵌套模板时,必须用typename声明是类型

举个例子:比如需要访问上面定义的MyTypes中下表为2的类型,推倒过程如下:

  1. TypeAt<MyTypes, 2>::Result
  2. => TypeAt<TypeList<int, TypeList<double, TypeList<std::string, void>>>, 2>::Result
  3. => TypeAt<TypeList<double, TypeList<std::string, void>>, 1>::Result
  4. => TypeAt<TypeList<std::string, void>, 0>::Result;
  5. => std::string

查找typelists的类型

定义:

cpp 复制代码
struct NullType;

template<typename TList, 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) };
};

说明:

首先声明主模板,再通过模板特化实现具体逻辑

递归终止条件1:当TypeList为NullType时,说明查找失败,value为-1

递归终止条件2:当Head类型为T时,说明找到了,返回0

递归逻辑推倒:去除当前节点类型,在剩余的节点中查找,查找结果递增。

举个例子,还是以MyTypes为例,查找std::string类型:

  1. IndexOf<TypeList<int, TypeList<double, TypeList<std::string, NullType>>>, std::string>::value
  2. 头类型int =/ std::string, 进行递归:1 + IndexOf<TypeList<double, TypeList<std::string, NullType>>, std::string>::value
  3. 头类型double=/ std::string,继续进行递归:1 + 1 + IndexOf<TypeList<std::string, NullType>, std::string>::value
  4. 头类型std::string==std::string,找到,结束递归,value=1+1+0=2

列表中添加新的类型

定义如下:

cpp 复制代码
template<typename TList, typename T>
struct Append;

template<>
struct Append<NullType, NullType> {
    typedef NullType Result;
};

template<typename T>
struct Append<NullType, T> {
    typedef TypeList<T, NullType> Result;
};

template<typename Head, typename Tail>
struct Append<NullType, TypeList<Head, Tail>> {
    typedef TypeList<Head, Tail> Result;
};

template<typename Head, typename Tail, typename T>
struct Append<TypeList<Head, Tail>, T> {
    typedef TypeList<Head, typename Append<Tail, T>::Result> Result;
};

移除列表中的某个元素

定义如下:

cpp 复制代码
template<typename TList, typename T>
struct Erase;

template<typename T>
struct Erase<NullType, T> {
    typedef NullType Result;
};

template<typename Tail, typename T>
struct Erase<TypeList<T, Tail>, T> {
    typedef Tail Result;
};

template<typename Head, typename Tail, typename T>
struct Erase<TypeList<Head, Tail>, T> {
    typedef typename TypeList<Head, typename Erase<Tail, T>::Result> Result;
};

template<typename TList, typename T>
struct EraseAll;

template<typename T>
struct EraseAll<NullType, T> {
    typedef NullType Result;
};

template<typename T, typename Tail>
struct EraseAll<TypeList<T, Tail>, T> {
    typedef typename EraseAll<Tail, T>::Result Result;
};

template<typename Head, typename Tail, typename T>
struct EraseAll<TypeList<Head, Tail>, T> {
    typedef typename TypeList<Head, typename EraseAll<Tail, T>::Result> Result;
};

删除重复元素

定义如下:

cpp 复制代码
template<typename TList>
struct NoDuplicate;

template<>
struct NoDuplicate<NullType> {
    typedef NullType Result;
};

template<typename Head, typename Tail>
struct NoDuplicate<TypeList<Head, Tail>> {
private:
    typedef typename NoDuplicate<Tail>::Result L1;
    typedef typename Erase<L1, Head>::Result L2;
public:
    typedef typename TypeList<Head, L2> Result;
};

取代TypeList中的某个元素

定义如下:

cpp 复制代码
template<typename TList, typename T, typename U>
struct Replace;

template<typename T, typename U>
struct Replace<NullType, T, U> {
    typedef NullType Result;
};

template<typename Tail, typename T, typename U>
struct Replace<TypeList<T, Tail>, T, U> {
    typedef TypeList<U, Tail> Result;
};

template<typename Head, typename Tail, typename T, typename U>
struct Replace<TypeList<Head, Tail>, T, U> {
    typedef typename Replace<TypeList<Tail>, T, U>::Result Temp;
    typedef typename TypeList<Head, Temp> Result;
};

长度获取

定义如下:

cpp 复制代码
template<typename TList>
struct Length;

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

template<typename Head, typename Tail>
struct Length<TypeList<Head, Tail>> {
    enum {
        value = 1 + Length<Tail>::value
    };
};
相关推荐
小小龙学IT几秒前
Python SQLAlchemy 2.0 深度解析:从 Core 到 ORM 的数据访问双引擎
开发语言·数据库·python
2601_962885723 分钟前
如何用 Python 计算 ROC 变动率指标做动量分析?
开发语言·python·算法
潼心1412o30 分钟前
C++初阶(长期更新)第9讲:string(上)
开发语言·c++
朝朝辞暮i42 分钟前
C++ 第 39 章: 阶段性总复习——类、对象、构造、继承、this、指针与智能指针
开发语言·c++·算法·ros2
wuminyu1 小时前
Virtual Thread重投递至ForkJoinPool任务队列过程解析
java·linux·c语言·jvm·c++
All for pursuit.1 小时前
【回溯-6】79.单词搜索
数据结构·c++·算法·leetcode
掉进电商坑三年没爬出来的东叔1 小时前
青龙面板进阶:一个面板聚合多平台签到,所有积分自动领
java·开发语言
iCxhust1 小时前
51单片机电力载波应用开发(七)广播通讯
c语言·开发语言·单片机·嵌入式硬件·51单片机
Benny_Tang2 小时前
AT_arc180_d [ARC180D] Division into 3 题解
数据结构·c++·算法
殷色玫瑰2 小时前
C++ STL:stack、queue、priority_queue 与容器适配器详解
java·开发语言·数据结构·c++·算法·visualstudio