后面再补, 先上码
#ifndef TYPELIST_H
#define TYPELIST_H
class NullType {};
template<class T, class U>
struct Typelist
{
typedef T Head;
typedef U Tail;
};
namespace TL
{
#define TYPELIST_1(T1) Typelist<T1, NullType>
#define TYPELIST_2(T1, T2) Typelist<T1, TYPELIST_1(T2)>
#define TYPELIST_3(T1, T2, T3) Typelist<T1, TYPELIST_2(T2, T3)>
#define TYPELIST_4(T1, T2, T3, T4) Typelist<T1, TYPELIST_3(T2, T3, T4)>
#define TYPELIST_5(T1, T2, T3, T4, T5) Typelist<T1, TYPELIST_4(T2, T3, T4, T5)>
#define TYPELIST_6(T1, T2, T3, T4, T5, T6) Typelist<T1, TYPELIST_5(T2, T3, T4, T5, T6)>
typedef TYPELIST_4(signed char, short int, int, long int) SignedIntegrals;
// Calculating the length of the typelist
template<class TList> struct Length;
template<> struct Length<NullType>
{
enum { value = 0 };
};
template<class T, class U>
struct Length<Typelist<T, U> >
{
enum { value = 1 + Length<U>::value };
};
// To obtain the type at specific index
template<class TList, unsigned int index> struct TypeAt;
template<class Head, class Tail>
struct TypeAt<Typelist<Head, Tail>, 0>
{
typedef Head Result;
};
template<class Head, class Tail, unsigned int i>
struct TypeAt<Typelist<Head, Tail>, i>
{
typedef typename TypeAt<Tail, i - 1>::Result Result;
};
// To obtain the index of the specified type in TypeList
template<class TList, class T> struct IndexOf;
template<class T>
struct IndexOf<NullType, T>
{
enum { value = -1 };
};
template<class T, class Tail>
struct IndexOf<Typelist<T, Tail>, T>
{
enum { value = 0 };
};
template<class Head, class Tail, class T>
struct IndexOf<Typelist<Head, Tail>, T>
{
private:
enum { temp = IndexOf<Tail, T>::value };
public:
enum { value = temp == -1 ? -1 : 1 + temp };
};
// Append a new type to the typelist
template<class TList, class T> struct Append;
template<> struct Append<NullType, NullType>
{
typedef NullType Result;
};
template<class T> struct Append<NullType, T>
{
typedef TYPELIST_1(T) Result;
};
template<class Head, class Tail>
struct Append<NullType, Typelist<Head, Tail> >
{
typedef Typelist<Head, Tail> Result;
};
template<class Head, class Tail, class T>
struct Append<Typelist<Head, Tail>, T>
{
typedef Typelist<Head, typename Append<Tail, T>::Result> Result;
};
// Erase a type from the typelist
template<class TList, class T> struct Erase;
template<class T>
struct Erase<NullType, T>
{
typedef NullType Result;
};
template<class T, class Tail>
struct Erase<Typelist<T, Tail>, T>
{
typedef Tail Result;
};
template<class Head, class Tail, class T>
struct Erase<Typelist<Head, Tail>, T>
{
typedef Typelist<Head, typename Erase<Tail, T>::Result> Result;
};
// Erase all occurences of a type in typelist
template<class TList, class T> struct EraseAll;
template<class T>
struct EraseAll<NullType, T>
{
typedef NullType Result;
};
template<class T, class Tail>
struct EraseAll<Typelist<T, Tail>, T>
{
typedef typename EraseAll<Tail, T>::Result Result;
};
template<class Head, class Tail, class T>
struct EraseAll<Typelist<Head, Tail>, T>
{
typedef Typelist<Head, typename EraseAll<Tail, T>::Result> Result;
};
// Make sure the typelist has no duplicates
template<class TList> struct NoDuplicates;
template<> struct NoDuplicates<NullType>
{
typedef NullType Result;
};
template<class Head, class Tail>
struct NoDuplicates<Typelist<Head, Tail> >
{
private:
typedef typename NoDuplicates<Tail>::Result L1;
typedef typename Erase<L1, Head>::Result L2;
public:
typedef Typelist<Head, L2> Result;
};
// Replace the first type T with type U in typelist
template <class TList, class T, class U> struct Replace;
template <class T, class U>
struct Replace<NullType, T, U>
{
typedef NullType Result;
};
template <class T, class Tail, class U>
struct Replace<Typelist<T, Tail>, T, U>
{
typedef Typelist<U, Tail> Result;
};
template <class Head, class Tail, class T, class U>
struct Replace<Typelist<Head, Tail>, T, U>
{
typedef Typelist<Head, typename Replace<Tail, T, U>::Result> Result;
};
// Replace all occurences of type T with U in typelist
template <class TList, class T, class U> struct ReplaceAll;
template <class T, class U>
struct ReplaceAll<NullType, T, U>
{
typedef NullType Result;
};
template <class T, class Tail, class U>
struct ReplaceAll<Typelist<T, Tail>, T, U>
{
typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
};
template <class Head, class Tail, class T, class U>
struct ReplaceAll<Typelist<Head, Tail>, T, U>
{
typedef Typelist<Head, typename ReplaceAll<Tail, T, U>::Result> Result;
};
}
#endif // TYPELIST_H
测试
#include <iostream>
using namespace std;
using namespace TL;
int main(int argc, char* argv[])
{
std::cout << "SignedIntegrals length is " << TL::Length<TL::SignedIntegrals>::value << std::endl;
std::cout << "sizeof(singed char) " << sizeof(TL::TypeAt<TL::SignedIntegrals,0>::Result) << std::endl;
std::cout << "sizeof(int) " << sizeof(TL::TypeAt<TL::SignedIntegrals,2>::Result) << std::endl;
std::cout << TL::IndexOf<TL::SignedIntegrals, char>::value << std::endl;
std::cout << TL::IndexOf<TL::SignedIntegrals, int>::value << std::endl;
std::cout << "The length of new typelist: "
<< TL::Length<TL::Append<TL::SignedIntegrals, TYPELIST_3(float, double, long double) >::Result>::value
<< std::endl;
std::cout << TL::Length<TL::Erase<TL::SignedIntegrals, int>::Result>::value << std::endl;
std::cout << TL::Length<TYPELIST_3(int, int, char)>::value << std::endl;
std::cout << TL::Length<TL::EraseAll<TYPELIST_3(int, int, char), int>::Result>::value << std::endl;
std::cout << TL::Length<TL::NoDuplicates<TYPELIST_3(int, int, char)>::Result>::value << std::endl;
std::cout << TL::Length<TL::NoDuplicates<
TL::Replace<TYPELIST_3(int, int, char), char, int>::Result>::Result>::value << std::endl;
std::cout << TL::Length<TL::NoDuplicates<
TL::ReplaceAll<TYPELIST_3(int, int, char), int, char>::Result>::Result>::value << std::endl;
return 0;
}
输出:
SignedIntegrals length is 4
sizeof(singed char) 1
sizeof(int) 4
-1
2
The length of new typelist: 7
4
3
1
2
1
1
解释
上面对typelist的操作均是利用递归模板. 实例化自身作为定义的一部分. 同时第一个的完全实例化是边界条件, 防止无限递归.