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
    };
};
相关推荐
Liekkas Kono7 小时前
RapidOCR Python 贡献指南
开发语言·python·rapidocr
张张努力变强7 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
xyq20247 小时前
Matplotlib 绘图线
开发语言
小镇敲码人7 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn
m0_694845577 小时前
tinylisp 是什么?超轻量 Lisp 解释器编译与运行教程
服务器·开发语言·云计算·github·lisp
平安的平安7 小时前
面向大模型算子开发的高效编程范式PyPTO深度解析
c++·mfc
June`7 小时前
muduo项目排查错误+测试
linux·c++·github·muduo网络库
春日见7 小时前
如何创建一个PR
运维·开发语言·windows·git·docker·容器
C++ 老炮儿的技术栈7 小时前
VS2015 + Qt 实现图形化Hello World(详细步骤)
c语言·开发语言·c++·windows·qt
派葛穆7 小时前
Python-批量安装依赖
开发语言·python