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.pswp.cn/news/895147.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895147.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895147.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

springboot 事務管理

在Spring Boot中&#xff0c;事務管理是通過Spring框架的事務管理模塊來實現的。Spring提供了聲明式事務管理和編程式事務管理兩種方式。通常&#xff0c;我們使用聲明式事務管理&#xff0c;因為它更簡潔且易于維護。 1. 聲明式事務管理 聲明式事務管理是通過注解來實現的。…

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文件來…

Leetcode 3448. Count Substrings Divisible By Last Digit

Leetcode 3448. Count Substrings Divisible By Last Digit 1. 解題思路2. 代碼實現 題目鏈接&#xff1a;3448. Count Substrings Divisible By Last Digit 1. 解題思路 這一題的話我們走的是一個累積數組的思路。 首先&#xff0c;我們使用一個cache數組記錄下任意段數字…

三維模擬-機械臂自翻車

機械仿真 前言效果圖后續 前言 最近在研究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;商…

2月9日QT

優化登錄框&#xff1a; 當用戶點擊取消按鈕&#xff0c;彈出問題對話框&#xff0c;詢問是否要確定退出登錄&#xff0c;并提供兩個按鈕&#xff0c;yes|No&#xff0c;如果用戶點擊的Yes&#xff0c;則關閉對話框&#xff0c;如果用戶點擊的No&#xff0c;則繼續登錄 當用戶…

安卓路由與aop 以及 Router-api

安卓路由&#xff08;Android Router&#xff09;和AOP&#xff08;面向切面編程&#xff09;是兩個在Android開發中常用的概念。下面我將詳細講解這兩個概念及其在Android開發中的應用。 一、安卓路由 安卓路由主要用于在應用程序中管理不同組件之間的導航和通信。它可以簡化…

大模型賦能網絡安全整體應用流程概述

一、四個階段概述 安全大模型的應用大致可以分為四個階段: 階段一主要基于開源基礎模型訓練安全垂直領域的模型; 階段二主要基于階段一訓練出來的安全大模型開展推理優化、蒸餾等工序,從而打造出不同安全場景的專家模型,比如數據安全領域、安全運營領域、調用郵件識別領…

nexus部署及配置https訪問

1. 使用docker-compose部署nexus docker-compose-nexus.yml version: "3" services:nexus:container_name: my-nexusimage: sonatype/nexus3:3.67.1hostname: my-nexusnetwork_mode: hostports:- 8081:8081deploy:resources:limits:cpus: 4memory: 8192Mreservations…

史上最快 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…

Docker從入門到精通- 容器化技術全解析

第一章&#xff1a;Docker 入門 一、什么是 Docker&#xff1f; Docker 就像一個超級厲害的 “打包神器”。它能幫咱們把應用程序和它運行所需要的東東都整整齊齊地打包到一起&#xff0c;形成一個獨立的小盒子&#xff0c;這個小盒子在 Docker 里叫容器。以前呢&#xff0c;…

ProcessingP5js數據可視化

折線圖繪制程序設計說明 可以讀取表格數據&#xff0c;并轉換成折線圖&#xff0c;條形圖和餅狀圖&#xff0c;并設計了銜接動畫效果 1. 功能概述 本程序使用 Processing 讀取 CSV 文件數據&#xff0c;并繪制帶有坐標軸和數據點的折線圖。橫坐標&#xff08;X 軸&#xff09…

使用云計算,企業的數據監管合規問題如何解決?

使用云計算&#xff0c;企業的數據監管合規問題如何解決&#xff1f; 在當今這個信息化、數字化的時代&#xff0c;數據無疑成為了企業最寶貴的資產之一。隨著云計算的普及&#xff0c;企業將大量數據存儲在云端&#xff0c;不僅提升了效率&#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_…

Flink (十七) :Table API SQL (五) 時區

Flink 為日期和時間提供了豐富的數據類型&#xff0c; 包括 DATE&#xff0c; TIME&#xff0c; TIMESTAMP&#xff0c; TIMESTAMP_LTZ&#xff0c; INTERVAL YEAR TO MONTH&#xff0c; INTERVAL DAY TO SECOND 。 Flink 支持在 session &#xff08;會話&#xff09;級別設置…