namespace tplt
{
//基本的操作接口
template <typename ... T>
class typelist
{
};
template <typename TPLT>
class front;
template <typename fisrt, typename ...other>
class front<typelist<fisrt, other...>>
{
public:
using type = fisrt;
};
template <typename TPLT>
class size;
template <typename ...args>
class size<typelist<args...>>
{
public:
static inline size_t value = sizeof...(args);
};
template <typename TPLT>
class pop_front;
template <typename fisrt, typename ...other>
class pop_front<typelist<fisrt, other...>>
{
public:
using type = typelist<other...>;
};
template <typename TPLT, typename NewElem>
class push_front;
template <typename ...Elem, typename NewElem>
class push_front<typelist<Elem...>, NewElem>
{
public:
using type = typelist<NewElem, Elem...>;
};
template <typename TPLT, typename NewElem>
class push_back;
template <typename ...Elem, typename NewElem>
class push_back<typelist<Elem...>, NewElem>
{
public:
using type = typelist<Elem..., NewElem>;
};
template <typename TPLT, typename NewElem>
class replace_front;
template <typename fisrt, typename ...other, typename NewElem>
class replace_front<typelist<fisrt, other...>, NewElem>
{
public:
using type = typelist<NewElem, other...>;
};
template <typename TPLT>
class is_empty
{
public:
static inline const bool value = false;
};
template <>
class is_empty<typelist<>>
{
public:
static inline const bool value = true;
};
//扩展
//找index的类型
template <typename TPLT, unsigned int index>
class find :public find<typename pop_front<TPLT>::type, index -1>
{
};
template <typename TPLT>
class find<TPLT, 0> :public front<TPLT>
{
};
//找到最大的元素
template <typename TPLT>
class get_maxsize_type
{
private:
//TPLT中的第一个元素
using tl_first_elem = typename front<TPLT>::type;
//TPLT中去掉第一个元素
using tl_remain = typename pop_front<TPLT>::type;
//递 归下去的get_maxsize_type中的typelist(模版参数)的第一个元素
using t1_first_elem_rec = typename get_maxsize_type<tl_remain>::type;
public:
using type = typename std::conditional<
sizeof(tl_first_elem) >= sizeof(t1_first_elem_rec),
tl_first_elem,
t1_first_elem_rec>::type;
};
template<>
class get_maxsize_type<typelist<>>
{
public:
using type = char;
};
//反转(reverse)
template <typename TPLT, bool = is_empty<TPLT>::value>
class reverse;
//有元素
template <typename TPLT>
class reverse<TPLT, false>
{
//TPLT中的第一个元素
using tl_first_elem = typename front<TPLT>::type;
using tl_result_rec = typename reverse<
typename pop_front<TPLT>::type>::type;
public:
using type = typename push_back<tl_result_rec, tl_first_elem>::type;
};
//无元素
template <typename TPLT>
class reverse<TPLT, true>
{
public:
using type = typename TPLT;//此时为typelist<>
};
}
using TPL_NM1 = tplt::typelist<int, double, float, char, bool>;
using TPL_NM2 = tplt::typelist<>;
namespace tplt2
{
class NullTypelist{};
template <typename T, typename U = NullTypelist>
class Typelist
{
public:
using Head = T;
using Tail = U;
private:
};
template<typename TPLT>
class front
{
public:
using type = typename TPLT::Head;
};
template <typename TPLT>
class size;
template<>
class size<NullTypelist>
{
public:
static inline size_t value = 0;
};
template<typename T, typename U>
class size<Typelist<T, U>>
{
public:
static inline size_t value = size<U>::value + 1;
};
template <typename TPLT>
class pop_front
{
public:
using type = typename TPLT::Tail;
};
template <typename TPLT, typename NewElem>
class push_front
{
public:
using type = Typelist<NewElem, TPLT>;
};
template <typename TPLT, typename NewElem>
class push_back
{
public:
using type = Typelist<TPLT, NewElem>;
};
template <typename TPLT>
class is_empty
{
public:
static inline const bool value = false;
};
template <>
class is_empty<NullTypelist>
{
public:
static inline const bool value = true;
};
//template <typename TPLT, unsigned int index>
//class find : public find<typename pop_front<TPLT>::type, index - 1>
//{
//};
//template <typename TPLT>
//class find<TPLT, 0> : public front<TPLT>
//{
//public:
//};
template <typename TPLT, unsigned int index>
class find;
template <typename Head, typename Tail>
class find<Typelist<Head, Tail>, 0>
{
public:
using type = Head;
};
template <typename Head, typename Tail, unsigned int index>
class find<Typelist<Head, Tail>, index>
{
public:
using type = typename find<Tail, index - 1>::type;
};
template <typename TPLT, unsigned int index, typename defaultType = NullTypelist>
class find_nostrict
{
public:
using type = defaultType;
};
template <typename Head, typename Tail, typename defaultType>
class find_nostrict<Typelist<Head, Tail>, 0, defaultType>
{
public:
using type = Head;
};
template <typename Head, typename Tail, unsigned int index, typename defaultType>
class find_nostrict<Typelist<Head, Tail>, index, defaultType>
{
public:
using type = typename find_nostrict<Tail, index -1, defaultType>::type;
};
template <typename Args>
class TestTPCloass
{
public:
using arg1 = typename find_nostrict<Args, 0>::type;
using arg2 = typename find_nostrict<Args, 1>::type;
using arg3 = typename find_nostrict<Args, 2>::type;
void func(arg1 v1, arg2 v2)
{
cout << v1 + v2 << endl;
}
};
}
#define MAC_TYPELIST1(T1) tplt2::Typelist<T1, tplt2::NullTypelist>
#define MAC_TYPELIST2(T1, T2) tplt2::Typelist<T1, MAC_TYPELIST1(T2)>
#define MAC_TYPELIST3(T1, T2, T3) tplt2::Typelist<T1, MAC_TYPELIST2(T2, T3)>
#define MAC_TYPELIST4(T1, T2, T3, T4) tplt2::Typelist<T1, MAC_TYPELIST3(T2, T3, T4)>
using TPL_NM3 = MAC_TYPELIST3(int, double, char);
int main()
{
std::cout << typeid(tplt::front<TPL_NM1>::type).name() << std::endl;
std::cout << tplt::size<TPL_NM1>::value << std::endl;
std::cout << typeid(tplt::pop_front<TPL_NM1>::type).name() << std::endl;
std::cout << typeid(tplt::push_front<TPL_NM1, bool>::type).name() << std::endl;
std::cout << typeid(tplt::push_back<TPL_NM1, bool>::type).name() << std::endl;
std::cout << typeid(tplt::replace_front<TPL_NM1, bool>::type).name() << std::endl;
std::cout << typeid(tplt::is_empty<TPL_NM1>::value).name() << std::endl;
std::cout << typeid(tplt::find<TPL_NM1, 2>::type).name() << std::endl;
std::cout << typeid(tplt::get_maxsize_type<TPL_NM1>::type).name() << std::endl;
std::cout << typeid(tplt::reverse<TPL_NM1>::type).name() << std::endl;
cout << typeid(tplt2::front<TPL_NM3>::type).name() << endl;
cout << tplt2::size<TPL_NM3>::value << endl;
cout << typeid(tplt2::pop_front<TPL_NM3>::type).name() << endl;
cout << typeid(tplt2::push_back<TPL_NM3, bool>::type).name() << endl;
cout << tplt2::is_empty<TPL_NM3>::value << endl;
cout << typeid(tplt2::find<TPL_NM3, 1>::type).name() << endl;
cout << typeid(tplt2::find_nostrict<TPL_NM3, 1>::type).name() << endl;
cout << typeid(tplt2::find_nostrict<TPL_NM3, 5>::type).name() << endl;
tplt2::TestTPCloass<TPL_NM3> obj;
obj.func(18, 19);
return 0;
}
get_maxsize_type 展开关系如下图

reverse//如下


本文介绍了一种使用模板元编程实现类型列表(typelist)的方法,包括基本操作如获取首个类型、计算列表大小、移除首个类型等,并展示了如何通过递归模板特化实现更复杂的功能如查找指定索引的类型、获取最大类型、反转类型列表等。
194

被折叠的 条评论
为什么被折叠?



