C++ type list 模板

C++ 实现一个type list 模板,在编译期计算。这个type list主要有构造,列表头类型,列表尾类型,concat操作,去除列表元素重复,获取指定元素,删除指定元素的操作。实现代码贴在下面:

cpp 复制代码
#pragma once
#include <iostream>
#include <typeinfo>


namespace type_list {
	// Step 1: 基础类型列表定义
	// 定义空列表
	template <typename ...Types>
	struct list {};

	// 非空列表的递归定义
	template <typename Type, typename ...Types>
	struct list<Type, Types...> {
		using head = Type;
		using tail = list<Types...>;
	};

	// 定义空列表类型
	using empty_list = list<>;

	// Step 2: 获取列表头部类型
	template <typename TypeList>
	using head_t = typename TypeList::head;

	// 获取列表尾部类型
	template <typename TypeList>
	using tail_t = typename TypeList::tail;

	// 构造新列表
	template <typename Head, typename Tail>
	struct construct;

	template <typename Head, typename Tail>
	using construct_t = typename construct<Head, Tail>::type;

	template <typename Head, typename ...Types>
	struct construct<Head, list<Types...>> {
		using type = list<Head, Types...>;
	};

	///

	template<typename TypeList>
	struct size;

	// 模板辅助类
	template<typename TypeList>
	constexpr size_t size_v = size<TypeList>::value;

	//size的模板特化,继承了std::integral_constant
	template<typename...Types>
	struct size<list<Types...>> : std::integral_constant<std::size_t, sizeof...(Types)> {};

	

	template<class TypeList>
	constexpr bool empty_v = (size_v<TypeList> == 0);

	template<class TypeList>
	struct empty : std::bool_constant<empty_v<TypeList>> {};

	template<class TypeList>
	constexpr bool empty_s = empty<TypeList>::value;

	/


	// 查找模板的制定索引的value
	//声明一个模板;
	template<std::size_t Index, class TypeList>
	struct get;

	template<std::size_t Index, class TypeList>
	using get_t = typename get<Index, TypeList>::type;

	template<std::size_t Index, class TypeList>
	struct get {
		using type = get_t<Index - 1, tail_t<TypeList>>;
	};

	template<class TypeList>
	struct get<0, TypeList> {
		using type = head_t<TypeList>;
	};

	/
	// concat
	template<typename TypeList1, typename TypeList2>
	class concat;

	template<typename T, typename U>
	using concat_t = typename concat<T, U>::type;

	template<typename ...T, typename ...U>
	class concat<list<T...>, list<U...>> {
	public:
		using type = list<T..., U...>;
	};

	
	// delete specific type

	template<typename TypeList, typename Type>
	class remove_all;

	template<typename TypeList, typename Type>
	using remove_all_t = typename remove_all<TypeList, Type>::type;


	template<typename TypeList, typename Type>
	class remove_all {
	public:
		using head = head_t<TypeList>;
		using tail = tail_t<TypeList>;
		using clean_tail = remove_all_t<tail, Type>;
		using type = std::conditional_t<std::is_same_v<head, Type>, clean_tail, construct_t<head, clean_tail>>;
	};

	template<typename Type>
	class remove_all<empty_list, Type> {
	public:
		using type = empty_list;
	};

	
	// get the last type
	template<typename TypeList>
	class last;

	template<typename TypeList>
	using last_t = typename last<TypeList>::type;

	template<typename TypeList>
	class last {
	public:
		using type = last_t<tail_t<TypeList>>;
	};

	// 递归终止
	template<typename Type>
	class last<list<Type>> {
	public:
		using type = Type;
	};

	
	// distinct list type
	template<typename TypeList>
	class distinct;

	template<typename TypeList>
	using distinct_t = typename distinct<TypeList>::type;

	template <typename TypeList>
	class distinct{
	public:
		using type = construct_t<
			head_t<TypeList>,
			distinct_t<
			remove_all_t<tail_t<TypeList>, head_t<TypeList>>>>;
	};

	// 递归终止
	template <>
	struct distinct<empty_list> {
		using type = empty_list;
	};

	
	// print list
	template<typename T>
	void print_type() {
		int status;
		std::cout << typeid(T).name() << std::endl;
	}

	// 打印类型列表
	template <typename TypeList>
	struct print_list;

	template <typename TypeList>
	void print_list_func() {
		print_list<TypeList>::print();
	}

	// 主模板,递归地打印类型列表
	template <typename TypeList>
	struct print_list {
		static void print() {
			print_type<head_t<TypeList>>();
			print_list_func<tail_t<TypeList>>();
		}
	};

	// 终止递归的特化版本
	template <>
	struct print_list<empty_list> {
		static void print() {
			// 空列表,不打印任何内容
		}
	};
	

} // namespace type_list

测试代码

cpp 复制代码
#pragma once

#include "type_list.h"
#include <iostream>

using namespace std;


void test_type_list() {

	//1.define list
	using MyList = type_list::list<int, double, char>;
	using AnotherList = type_list::list<float, int>;

	using EmptyList = type_list::list<>;

	//2. get the head and tail type of list
	using MyListHead = type_list::head_t<MyList>;
	using MyListTail = type_list::tail_t<MyList>;
	static_assert(std::is_same_v<MyList::tail, type_list::list<double,char>>, "MyList head shoud be int");
	static_assert(std::is_same_v<MyListTail, type_list::list<double, char>>, "MyList head shoud be int");
	static_assert(std::is_same_v<MyListHead, int>, "MyList head shoud be int");
	static_assert(std::is_same_v<MyList::head, int>, "MyList head shoud be int");


	//3. get list size
	constexpr std::size_t listSize = type_list::size_v<MyList>;
	std::cout << listSize << std::endl;

	// 4. empty
	static_assert(type_list::empty_s<EmptyList>, "is empty");
	static_assert(type_list::empty_v<EmptyList>, "is empty");


	// 5. get index pos
	using FirstType = type_list::get_t<1, MyList>;
	static_assert(std::is_same_v<FirstType, double>, "not equal");

	// 6.concat list
	using ConcatList = type_list::concat_t<MyList, AnotherList>;
	using ConcatListHead = type_list::head_t<ConcatList>;
	static_assert(std::is_same_v<ConcatListHead, int>, "head should be int");
	static_assert(std::is_same_v<ConcatList::head, int>, "head should be int");

	constexpr std::size_t concat_list_size = type_list::size_v<ConcatList>;
	cout << "concat_list_size : " << concat_list_size << endl;

	// 6.delete list type
	using RemoveIntList = type_list::remove_all<MyList, int>;
	static_assert(std::is_same_v<type_list::head_t<RemoveIntList>, int>, "the list head shoud not be int");

	// 6.delete list type
	using LastType = type_list::last_t<MyList>;

	static_assert(std::is_same_v<LastType, char>, "the last type should be char");

	// distinct list type
	using RepeatList = type_list::list<int, double, char, int, double, char, int,int,int>;
	using DistType = type_list::distinct_t<RepeatList>;

	std::cout << "--------------------------" << endl;
	type_list::print_list_func<RepeatList>();
	std::cout << "--------------------------" << endl;
	type_list::print_list_func<DistType>();
	std::cout << "--------------------------" << endl;

}
相关推荐
染指11102 小时前
50.第二阶段x86游戏实战2-lua获取本地寻路,跨地图寻路和获取当前地图id
c++·windows·lua·游戏安全·反游戏外挂·游戏逆向·luastudio
Code out the future2 小时前
【C++——临时对象,const T&】
开发语言·c++
sam-zy2 小时前
MFC用List Control 和Picture控件实现界面切换效果
c++·mfc
dntktop3 小时前
Converseen:全能免费批量图像处理专家
windows
aaasssdddd963 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
发呆小天才O.oᯅ3 小时前
YOLOv8目标检测——详细记录使用OpenCV的DNN模块进行推理部署C++实现
c++·图像处理·人工智能·opencv·yolo·目标检测·dnn
qincjun4 小时前
文件I/O操作:C++
开发语言·c++
星语心愿.4 小时前
D4——贪心练习
c++·算法·贪心算法
汉克老师4 小时前
2023年厦门市第30届小学生C++信息学竞赛复赛上机操作题(三、2023C. 太空旅行(travel))
开发语言·c++
一个懒鬼4 小时前
Windows脚本清理C盘缓存
windows·缓存