C++模板编程——typelist的实现

文章最后给出了汇总的代码,可直接运行

1. typelist是什么

typelist是一种用来操作类型的容器。和我们所熟知的vector、list、deque类似,只不过typelist存储的不是变量,而是类型。

typelist简单来说就是一个类型容器,能够提供一系列的操作。

本文将展示使用元编程实现typelist。

2. 要实现的typelist的接口

在此列举一下即将要编写的typelist的所有接口:

  • typelist:要实现的容器类型。
  • front<typelist>:获取容器中的第一个元素。
  • size<typelist>:获取容器的元素数量。
  • pop_front<typelist, elem>:移出第一个元素。
  • push_front<typelist, elem>:向开头插入一个元素。
  • push_back<typelist, elem>:向结尾插入一个元素。
  • replace_front<typelist, elem>:替换第一个元素。
  • is_empty<typelist>:判断是否为空。
  • find<typelist, index>:查找下标为index的元素。
  • get_maxsize_type<typelist>:容器中尺寸(sizeof)最大的元素。
  • reverse<typelist>:翻转容器中的元素。 

3. 接口实现

3.1 容器

template<typename... Elems>
struct typelist{};

3.2 front<typelist>

template<typename TPLT>// typelist的简写
struct front;struct front<typelist<FirstElem, OtherElems...>>
{using type = FirstElem;
};

3.3 size<typelist>

template<typename TPLT>
struct size;template<typename... Elems>
struct size<typelist<Elems...>>
{static inline const value = sizeof...(Elems);
};

3.4 pop_front<typelist, elem>

template<typename TPLT>
struct pop_front;template<typename FirstElem, typename... OtherElems>
struct pop_front<typelist<FirstElem, OtherElems...>
{using type = typelist<OtherrElems...>;
};

3.5 push_front<typelist, elem>

template<typename TPLT, typename newElem>
struct push_front;template<typename... Elems, typename newElem>
struct push_front<typelist<Elems...>, newElem>
{using type = typelist<newElem, Elems...>;
};

3.6 push_back<typelist, elem>

template<typename TPLT, typename newElem>
struct push_back;template<typename... Elems, typename newElem>
struct push_back<typelist<Elems...>, newElem>
{using type = typelist<Elems..., newElem>;
};

3.7 replace_front<TPLT, elem>

template<typename TPLT, typename Elem>
struct replace_front;template<typename FirstElem, typename... OtherElems, typename Elem>
struct replace_front<typelist<FirstElem, OtherElems...>, Elem>
{using type = typelist<Elem, OtherElems...>;
};

3.8 is_empty<TPLT>

template<typename TPLT>
struct is_empty;template<typename... Elems>
struct is_empty
{static inline const bool value = sizeof...(Elems) == 0;
};

3.9 find<typelist, index>

template<typename TPLT, size_t index>
struct find : find<typename pop_front<TPLT>::type, index - 1>
{};template<typename TPLT>
struct find<TPLT, 0> :front<TPLT>
{
};

3.10 get_maxsize_type<typelist>

template<typename TPLT>
struct get_maxsize_type
{
private:using FirstType = typename front<TPLT>::type;using RemainLT = typename pop_front<TPLT>::type;using RemainMaxType = typename get_maxsize_type<RemainLT>::type;
public:using type = conditional_t < (sizeof(FirstType) > sizeof(RemainMaxType)),FirstType, RemainMaxType >;
};template<typename Elem>
struct get_maxsize_type<typelist<Elem>>
{using type = Elem;
};template<>
struct get_maxsize_type<typelist<>>;

3.11 reverse<typelist>

template<typename TPLT>
struct reverse
{
private:using FirstElem = typename front<TPLT>::type;using RemainTL = typename pop_front<TPLT>::type;using ReversedRemainTL = typename reverse<RemainTL>::type;
public:using type = typename push_back<ReversedRemainTL, FirstElem>::type;
};template<>
struct reverse<typelist<>>
{using type = typelist<>;
};

template<typename TPLT, bool = is_empty<TPLT>::value>
struct reverse;template<typename TPLT>
struct reverse<TPLT, false>
{
private:using FirstElem = typename front<TPLT>::type;using RemainTL = typename pop_front<TPLT>::type;using ReversedRemainTL = typename reverse<RemainTL>::type;
public:using type = typename push_back<ReversedRemainTL, FirstElem>::type;
};template<typename TPLT>
struct reverse<TPLT, true>
{using type = typelist<>;
};

4. 完整代码

 

#include <iostream>
#include <string>
#include "boost/type_index.hpp"using namespace std;template<typename T>
class TypeGetter
{
public:static inline const std::string name = boost::typeindex::type_id_with_cvr<T>().pretty_name();
};namespace myTypeList
{template<typename... T>struct typelist {};template<typename TPLT>struct front;template<typename FirstType, typename... Others>struct front < typelist<FirstType, Others...>>{using type = FirstType;};template<typename TPLT>struct size;template<typename... Args>struct size<typelist<Args...>>{static const inline size_t value = sizeof...(Args);};template<typename TPLT>struct is_empty;template<typename... Elems>struct is_empty<typelist<Elems...>>{static constexpr bool value = sizeof...(Elems) == 0;};template<typename TPLT>struct pop_front;template<typename FirstType, typename... Others>struct pop_front< typelist<FirstType, Others...> >{using type = typelist<Others...>;};template<typename TPLT, typename T>struct push_front;template<typename... Types, typename T>struct push_front<typelist<Types...>, T>{using type = typelist<T, Types...>;};template<typename TPLT, typename T>struct push_back;template<typename... Types, typename T>struct push_back<typelist<Types...>, T>{using type = typelist<Types..., T>;};template<typename TPLT, typename newElem>struct replace_front;template<typename FirstElem, typename... OtherElems, typename newElem>struct replace_front<typelist<FirstElem, OtherElems...>, newElem>{using type = typelist<newElem, OtherElems...>;};template<typename TPLT, size_t index>struct find : find<typename pop_front<TPLT>::type, index - 1>{};/*和下面的写法是等价的template<typename TPLT, size_t index>struct find{using type = typename find<typename pop_front<TPLT>::type, index - 1>::type;};*/template<typename TPLT>struct find<TPLT, 0> :front<TPLT>{};/*get_maxsize_type: 获取typelist中尺寸最大的类型*/template<typename TPLT>struct get_maxsize_type{private:using FirstType = typename front<TPLT>::type;using RemainLT = typename pop_front<TPLT>::type;using RemainMaxType = typename get_maxsize_type<RemainLT>::type;public:using type = conditional_t < (sizeof(FirstType) > sizeof(RemainMaxType)),FirstType, RemainMaxType >;};template<typename Elem>struct get_maxsize_type<typelist<Elem>>{using type = Elem;};template<>struct get_maxsize_type<typelist<>>;/*reverse: 翻转typelist*//*// 版本一template<typename TPLT>struct reverse{private:using FirstElem = typename front<TPLT>::type;using RemainTL = typename pop_front<TPLT>::type;using ReversedRemainTL = typename reverse<RemainTL>::type;public:using type = typename push_back<ReversedRemainTL, FirstElem>::type;};template<>struct reverse<typelist<>>{using type = typelist<>;};*/template<typename TPLT, bool = is_empty<TPLT>::value>struct reverse;template<typename TPLT>struct reverse<TPLT, false>{private:using FirstElem = typename front<TPLT>::type;using RemainTL = typename pop_front<TPLT>::type;using ReversedRemainTL = typename reverse<RemainTL>::type;public:using type = typename push_back<ReversedRemainTL, FirstElem>::type;};template<typename TPLT>struct reverse<TPLT, true>{using type = typelist<>;};
}class A {};int main()
{using TPL_1 = myTypeList::typelist<char, short, int, A, double>;using TPL_2 = myTypeList::typelist<>;cout << "TPL_1 的第一个类型为" << TypeGetter< myTypeList::front<TPL_1>::type >::name << endl;//cout << "TPL_2 的第一个类型为" << TypeGetter< myTypeList::front<TPL_2>::type >::name << endl;cout << "TPL_1 的size为:" << myTypeList::size<TPL_1>::value << endl;cout << "TPL_2 的size为:" << myTypeList::size<TPL_2>::value << endl;cout << "TPL_1 的pop_front为:" << TypeGetter< myTypeList::pop_front< TPL_1 >::type >::name << endl;//cout << "TPL_2 的pop_front为:" << TypeGetter< myTypeList::pop_front< TPL_2 >::type >::name << endl;cout << "TPL_1 push_front bool 为:" << TypeGetter< myTypeList::push_front<TPL_1, bool>::type>::name << endl;cout << "TPL_2 push_front bool 为:" << TypeGetter< myTypeList::push_front<TPL_2, bool>::type>::name << endl;cout << "TPL_1 push_back bool 为:" << TypeGetter< myTypeList::push_back<TPL_1, bool>::type>::name << endl;cout << "TPL_2 push_back bool 为:" << TypeGetter< myTypeList::push_back<TPL_2, bool>::type>::name << endl;cout << "TPL_1 replace_front with char 为:" << TypeGetter < myTypeList::replace_front< TPL_1, char >::type>::name << endl;cout << "TPL_1 index 2 type 为:" << TypeGetter< myTypeList::find<TPL_1, 2>::type > ::name << endl;cout << "TPL_1 max size type 为:" << TypeGetter<myTypeList::get_maxsize_type<TPL_1>::type>::name << endl;cout << "TPL_1         为:" << TypeGetter<TPL_1>::name << endl;cout << "TPL_1 reverse 为:" << TypeGetter<myTypeList::reverse<TPL_1>::type>::name << endl;return 0;
}

 运行结果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/895147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows通过网络向Ubuntu发送文件/目录

由于最近要使用树莓派进行一些代码练习&#xff0c;但是好多东西都在windows里或虚拟机上&#xff0c;就想将文件传输到树莓派上&#xff0c;但试了发现u盘不能简单传送&#xff0c;就在网络上找到了通过windows 的scp命令传送 前提是树莓派先开启ssh服务&#xff0c;且Window…

字节跳动后端一面

&#x1f4cd;1. Gzip压缩技术详解 Gzip是一种流行的无损数据压缩格式&#xff0c;它使用DEFLATE算法来减少文件大小&#xff0c;广泛应用于网络传输和文件存储中以提高效率。 &#x1f680; 使用场景&#xff1a; • 网站优化&#xff1a;通过压缩HTML、CSS、JavaScript文件来…

三维模拟-机械臂自翻车

机械仿真 前言效果图后续 前言 最近在研究Unity机械仿真&#xff0c;用Unity实现其运动学仿真展示的功能&#xff0c;发现一个好用的插件“MGS-Machinery-master”&#xff0c;完美的解决了Unity关节定义缺少液压缸伸缩关节功能&#xff0c;内置了多个场景&#xff0c;讲真的&…

USB子系统学习(四)用户态下使用libusb读取鼠标数据

文章目录 1、声明2、HID协议2.1、描述符2.2、鼠标数据格式 3、应用程序4、编译应用程序5、测试6、其它 1、声明 本文是在学习韦东山《驱动大全》USB子系统时&#xff0c;为梳理知识点和自己回看而记录&#xff0c;全部内容高度复制粘贴。 韦老师的《驱动大全》&#xff1a;商…

史上最快 Python版本 Python 3.13 安装教程

Python3.13安装和配置 一、Python的下载 1. 网盘下载地址 (下载速度比较快&#xff0c;推荐&#xff09; Python3.13.0下载&#xff1a;Python3.13.0下载地址&#xff08;windows&#xff09;3.13.0下载地址&#xff08;windows&#xff09; 点击下面的下载链接&#xff0c…

AWS Fargate

AWS Fargate 是一个由 Amazon Web Services (AWS) 提供的无服务器容器计算引擎。它使开发者能够运行容器化应用程序&#xff0c;而无需管理底层的服务器或虚拟机。简而言之&#xff0c;AWS Fargate 让你只需关注应用的容器本身&#xff0c;而不需要管理运行容器的基础设施&…

vue3+vite+eslint|prettier+elementplus+国际化+axios封装+pinia

文章目录 vue3 vite 创建项目如果创建项目选了 eslint prettier从零教你使用 eslint prettier第一步&#xff0c;下载eslint第二步&#xff0c;创建eslint配置文件&#xff0c;并下载好其他插件第三步&#xff1a;安装 prettier安装后配置 eslint (2025/2/7 补充) 第四步&am…

vLLM V1 重磅升级:核心架构全面革新

本文主要是 翻译简化个人评读&#xff0c;原文请参考&#xff1a;vLLM V1: A Major Upgrade to vLLM’s Core Architecture vLLM V1 开发背景 2025年1月27日&#xff0c;vLLM 开发团队推出 vLLM V1 alpha 版本&#xff0c;这是对框架核心架构的里程碑式升级。基于过去一年半的…

Jupyter Notebook自动保存失败等问题的解决

一、未生成配置文件 需要在命令行中&#xff0c;执行下面的命令自动生成配置文件 jupyter notebook --generate-config 执行后会在 C:\Users\用户名\.jupyter目录中生成文件 jupyter_notebook_config.py 二、在网页端打开Jupyter Notebook后文件保存失败&#xff1b;运行代码…

使用wpa_supplicant和wpa_cli 扫描wifi热点及配网

一&#xff1a;简要说明 交叉编译wpa_supplicant工具后会有wpa_supplicant和wpa_cli两个程序生产&#xff0c;如果知道需要连接的wifi热点及密码的话不需要遍历及查询所有wifi热点的名字及信号强度等信息的话&#xff0c;使用wpa_supplicant即可&#xff0c;否则还需要使用wpa_…

【真一键部署脚本】——一键部署deepseek

目录 deepseek一键部署脚本说明 0 必要前提 1 使用方法 1.1 使用默认安装配置 1.1 .1 使用其它ds模型 1.2 使用自定义安装 2 附录&#xff1a;deepseek模型手动下载 3 脚本下载地址 deepseek一键部署脚本说明 0 必要前提 linux环境 python>3.10 1 使用方法 1.1 …

5.2Internet及其作用

5.2.1Internet概述 Internet称为互联网&#xff0c;又称英特网&#xff0c;始于1969年的美国ARPANET&#xff08;阿帕网&#xff09;&#xff0c;是全球性的网络。 互连网指的是两个或多个不同类型的网络通过路由器等网络设备连接起来&#xff0c;形成一个更大的网络结构。互连…

“图像识别分割算法:解锁视觉智能的关键技术

嘿&#xff0c;各位朋友&#xff01;今天咱们来聊聊图像识别分割算法。这可是计算机视觉领域里特别厉害的一项技术&#xff0c;简单来说&#xff0c;它能让机器“看懂”图像中的不同部分&#xff0c;并把它们精准地分出来。想象一下&#xff0c;机器不仅能识别出图里有猫还是狗…

AJAX项目——数据管理平台

黑马程序员视频地址&#xff1a; 黑马程序员——数据管理平台 前言 功能&#xff1a; 1.登录和权限判断 2.查看文章内容列表&#xff08;筛选&#xff0c;分页&#xff09; 3.编辑文章&#xff08;数据回显&#xff09; 4.删除文章 5.发布文章&#xff08;图片上传&#xff0…

html转PDF文件最完美的方案(wkhtmltopdf)

目录 需求 一、方案调研 二、wkhtmltopdf使用 如何使用 文档简要说明 三、后端服务 四、前端服务 往期回顾 需求 最近在做报表类的统计项目&#xff0c;其中有很多指标需要汇总&#xff0c;网页内容有大量的echart图表&#xff0c;做成一个网页去浏览&#xff0c;同时…

示例:JAVA调用deepseek

近日&#xff0c;国产AI DeepSeek在中国、美国的科技圈受到广泛关注&#xff0c;甚至被认为是大模型行业的最大“黑马”。在外网&#xff0c;DeepSeek被不少人称为“神秘的东方力量”。1月27日&#xff0c;DeepSeek应用登顶苹果美国地区应用商店免费APP下载排行榜&#xff0c;在…

.NET周刊【2月第1期 2025-02-02】

国内文章 dotnet 9 已知问题 默认开启 CET 导致进程崩溃 https://www.cnblogs.com/lindexi/p/18700406 本文记录 dotnet 9 的一个已知且当前已修问题。默认开启 CET 导致一些模块执行时触发崩溃。 dotnet 使用 ColorCode 做代码着色器 https://www.cnblogs.com/lindexi/p/…

AES200物理机部署DeepSeek-R1蒸馏模型

AES200物理机部署DeepSeek-R1模型 华为官方官宣自己的NPU支持DeepSeek-R1模型部署&#xff0c;华为的大模型推理部署依托于其大模型推理引擎&#xff1a;MindIE&#xff0c;但是根据MindIE的文档&#xff0c;其只支持以下硬件&#xff1a; 表1 MindIE支持的硬件列表 类型配置…

【后端开发】系统设计101——Devops,Git与CICD,云服务与云原生,Linux,安全性,案例研究(30张图详解)

【后端开发】系统设计101——Devops&#xff0c;Git与CICD&#xff0c;云服务与云原生&#xff0c;Linux&#xff0c;安全性&#xff0c;案例研究&#xff08;30张图详解&#xff09; 文章目录 1、DevopsDevOps与SRE与平台工程的区别是什么&#xff1f;什么是k8s&#xff08;Ku…

正泰中间电磁继电器【8脚10A】DC24V 待机功率

需求&#xff1a;继电器能耗测试。 1.连接24V2A的电源&#xff0c; 2. 稳定功率为 1.4W 3. 正泰中间电磁继电器【8脚10A】直流DC24V 注&#xff1a;联通时电磁继电器会轻微发热 4.电磁继电器的工作原理基于电流的磁效应 电磁激励&#xff1a;电磁继电器主要由线圈、铁芯、衔…