马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
文章最后给出了汇总的代码,可直接运行
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>:翻转容器中的元素。
- filter<typelist, Pre>:根据谓词Pre来过滤typelist中的类型。Pre应该是一个类模板,接受一个类型模板参数,并拥有一个bool类型的静态变量value,value为false时将该类型剔除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<>;
- };
复制代码 3.12 filter<typelist, Pre>
- // 根据谓词过滤元素,谓词应该是一个类模板,接受一个类型参数,并且具有静态bool变量,false表示过滤掉该类型
- template<typename TPLT, template<typename>typename Pre>
- struct filter;
- template<typename FirstElem, typename... OtherElems, template<typename>typename Pre>
- struct filter<typelist<FirstElem, OtherElems...>, Pre>
- {
- private:
- using RemainFilteredTL = typename filter<typelist<OtherElems...>, Pre>::type;
- public:
- using type = std::conditional_t< Pre<FirstElem>::value,
- typename push_front<RemainFilteredTL, FirstElem>::type,
- RemainFilteredTL >;
- };
- template<template<typename>typename Pre>
- struct filter<typelist<>, Pre>
- {
- using type = typelist<>;
- };
复制代码- // 测试使用的类模板,用以剔除某个指定的类型
- template<typename InputType, typename FilterType = double>
- struct test_filter
- {
- static constexpr bool value = !std::is_same_v<InputType, FilterType>; //如果类型是int,就输出false,int不通过
- };
复制代码
4. 完备代码
- #include <iostream>
- #include <type_traits>
- #include "typegetter.hpp"
- using namespace std;
- /*
- */
- namespace myTypeList
- {
- template<typename... Elems>
- struct typelist {};
- template<typename TPLT>
- struct front;
- template<typename FirstElem, typename... OtherElems>
- struct front < typelist<FirstElem, OtherElems...>>
- {
- using type = FirstElem;
- };
- template<typename TPLT>
- struct size;
- template<typename... Elems>
- struct size<typelist<Elems...>>
- {
- static const inline size_t value = sizeof...(Elems);
- };
- 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 FirstElem, typename... OtherElems>
- struct pop_front< typelist<FirstElem, OtherElems...> >
- {
- using type = typelist<OtherElems...>;
- };
- template<typename TPLT, typename newElem>
- struct push_front;
- template<typename... Types, typename newElem>
- struct push_front<typelist<Types...>, newElem>
- {
- using type = typelist<newElem, Types...>;
- };
- template<typename TPLT, typename newElem>
- struct push_back;
- template<typename... Types, typename newElem>
- struct push_back<typelist<Types...>, newElem>
- {
- using type = typelist<Types..., newElem>;
- };
- 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 FirstElem = typename front<TPLT>::type;
- using RemainLT = typename pop_front<TPLT>::type;
- using RemainMaxElem = typename get_maxsize_type<RemainLT>::type;
- public:
- using type = conditional_t < (sizeof(FirstElem) > sizeof(RemainMaxElem)),
- FirstElem, RemainMaxElem >;
- };
- 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<>;
- };
- // 根据谓词过滤元素,谓词应该是一个类模板,接受一个类型参数,并且具有静态bool变量,false表示过滤掉该类型
- template<typename TPLT, template<typename>typename Pre>
- struct filter;
- template<typename FirstElem, typename... OtherElems, template<typename>typename Pre>
- struct filter<typelist<FirstElem, OtherElems...>, Pre>
- {
- private:
- using RemainFilteredTL = typename filter<typelist<OtherElems...>, Pre>::type;
- public:
- using type = std::conditional_t< Pre<FirstElem>::value,
- typename push_front<RemainFilteredTL, FirstElem>::type,
- RemainFilteredTL >;
- };
- template<template<typename>typename Pre>
- struct filter<typelist<>, Pre>
- {
- using type = typelist<>;
- };
- }
- class A {};
- // 测试使用的类模板,用以剔除某个指定的类型
- template<typename InputType, typename FilterType = double>
- struct test_filter
- {
- static constexpr bool value = !is_same_v<InputType, FilterType>; //如果类型是int,就输出false,int不通过
- };
- int main()
- {
- using TPL_1 = myTypeList::typelist<char, short, char, int, double, int, long, A, double>;
- using TPL_2 = myTypeList::typelist<>;
- cout << "----------------------------------" << endl;
- cout << "TPLT_1 为:" << TypeGetter<TPL_1>::name << endl;
- cout << "TPLT_2 为:" << TypeGetter<TPL_2>::name << endl;
- cout << "----------------------------------" << endl;
- 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;
- cout << "TPL_1 经过int_filter过滤为:" << TypeGetter<myTypeList::filter<TPL_1, test_filter>::type>::name << endl;
- cout << "TPL_2 经过int_filter过滤为:" << TypeGetter<myTypeList::filter<TPL_2, test_filter>::type>::name << endl;
- return 0;
- }
复制代码 typegetter.hpp的代码如下所示:
- #pragma once
- #include <string>
- #include "boost/type_index.hpp"
- template<typename T>
- class TypeGetter
- {
- public:
- static inline const std::string name = boost::typeindex::type_id_with_cvr<T>().pretty_name();
- };
复制代码
运行结果如下:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |