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
    };
};
相关推荐
u0104058362 小时前
Java应用的链路追踪:实现分布式跟踪
java·开发语言·分布式
这是个栗子2 小时前
【API封装参数传递】params 与 API 封装
开发语言·前端·javascript·data·params
27669582922 小时前
vercel 安全检测逆向 x-vercel-challenge-solution
开发语言·python·solution·vercel-solution·x-vercel·vercel逆向·ensun
傻乐u兔2 小时前
C语言初阶————调试实用技巧1
c语言·开发语言
Sammyyyyy2 小时前
Gemini CLI 进阶:构建安全的MCP连接与验证策略
开发语言·ai·ai编程·servbay
老蒋每日coding2 小时前
驾驭并发之力:Go语言构建高可用微服务完全指南
开发语言·微服务·golang
努力学习的小洋2 小时前
Python训练打卡Day4:缺失值处理
开发语言·python
郝学胜-神的一滴2 小时前
Python类属性与实例属性详解及MRO算法演进
开发语言·python·程序人生·算法
一颗青果2 小时前
短线重连代码实现
开发语言·网络·c++