Typelists(一)
实现部分
Typelists.h
//想想看一个std::pair变量能够拥有无数的变量 //如果元素不是变量而是类型,会是什么景象呢? template<class T, class U> struct TypePair { typedef T First; typedef U Second; }; //如同c字符串,使用一个人为定义的空类来作为结束 struct NullType; //方便使用,定义出不同数目的由TypePair构成的类型链表的宏 #define Typelists_1(T1) TypePair<T1, NullType> #define Typelists_2(T1, T2) TypePair<T1, Typelists_1(T2)> #define Typelists_3(T1, T2, T3) TypePair<T1, Typelists_2(T2, T3)> #define Typelists_4(T1, T2, T3, T4) TypePair<T1, Typelists_3(T2, T3, T4)> //就先写这么多吧 //如何知道这个Typelist的长度呢?,看宏定义?太傻了吧 //利用一个模板类完成这一功能,想想看如果没有NullType应该怎么做 //首先是一个模板声明,只声明的目的是只用它的特化版本 template <class TList> class Length; //如果模板参数的是Typelists_1,返回1 template <class T> struct Length<Typelists_1(T)> { enum{length = 1}; }; //如果模板参数是普通TypePair,返回Second的长度 + 1 template<class T, class U> struct Length<TypePair<T, U>> { enum{length = 1 + Length<U>::length}; }; //其余情况就是传入参数有问题了,不是一个TypePair //如果需要从Typelists_x中找出第index个类型该如何办? //利用一个模板类完成这一功能 template<class TList, unsigned index> struct TypeAt; //如果这个链表有 > 0 个类型,且index == 0,返回Head template<class T, class U> struct TypeAt<TypePair<T, U>, 0> { typedef T Result; }; //如果这个链表有 > 0 个类型,且index > 0,返回Tail部分的index - 1(除去First这个类型)号类型 template<class T, class U, unsigned index> struct TypeAt<TypePair<T, U>, index> { typedef typename TypeAt<U, index - 1>::Result Result;//注意这个typename关键字 }; //其他情况统统没有实现,要想得到不在链表范围内的类型,只会得到编译器的谴责 //返回某个index的编号的类型实现了,那么返回某个类型的编号又如何实现呢? //利用一个模板类完成这一功能(如果存在这个类型就返回这个类型的编号,否则为-1) template<class T, class TList> struct UpIndexOf; ////如果Typelists_1中的First和需要查找的类型同类型,index = 0 //template<class T> //struct UpIndexOf<T, Typelists_1(T)> //{ // enum{index = 0}; //}; ////如果Typelists_1中的First和需要查找的类型 不是 同类型,index = -1 //template<class T, class U> //struct UpIndexOf<T, Typelists_1(U)> //{ // enum{index = -1}; //}; //更简单,美观的办法是 template<class T> struct UpIndexOf<T, NullType> { enum{index = -1}; }; /* 查询一般的TypePair中T的编号 如果First是该类型 如果Second的index是-1 此时index为0 否则 index = Second 的 index + 1 否则 如果Second的index是-1 此时index为-1 否则 index = Second 的 index + 1 */ template<class T, class U> struct UpIndexOf<T, TypePair<T, U>> { enum { temp = UpIndexOf<T, U>::index, index = temp == -1 ? 0 : (temp + 1) }; }; template<class T, class U, class V> struct UpIndexOf<T, TypePair<U, V>> { enum { temp = UpIndexOf<T, V>::index, index = temp == -1 ? -1 : (temp + 1) }; }; //以上是以最远处出现该类型的位置作为返回位置 //再实现一个以最近处出现该类型的位置作为返回位置 template<class T, class TList> struct LowIndexOf; template<class T, class U> struct LowIndexOf<T, TypePair<T, U>> { enum{index = 0}; }; template<class T, class U, class V> struct LowIndexOf<T, TypePair<U, V>> { enum { temp = LowIndexOf<T, V>::index, index = temp == -1 ? -1 : temp + 1 }; }; template<class T> struct LowIndexOf<T, NullType> { enum{index = -1}; };
测试部分
Typelists.cpp
#include <iostream> using namespace std; #include "Typelists.h" int main() { typedef Typelists_4(char, unsigned char, signed char, wchar_t) CharList; cout << Length<CharList>::length << endl; TypeAt<CharList, 0>::Result c0; TypeAt<CharList, 1>::Result c1; TypeAt<CharList, 2>::Result c2; TypeAt<CharList, 3>::Result c3; /* error C2027: 使用了未定义类型“TypeAt<TList,index>” with [ TList=NullType, index=0 ] */ //TypeAt<CharList, 4>::Result c4; cout << typeid(c0).name() << endl; cout << typeid(c1).name() << endl; cout << typeid(c2).name() << endl; cout << typeid(c3).name() << endl; //cout << typeid(c4).name() << endl; typedef Typelists_4(char, int, int, double) UnuniqueList; cout << UpIndexOf<char, UnuniqueList>::index <<endl; cout << UpIndexOf<int, UnuniqueList>::index <<endl; cout << UpIndexOf<double, UnuniqueList>::index <<endl; cout << LowIndexOf<char, UnuniqueList>::index <<endl; cout << LowIndexOf<int, UnuniqueList>::index <<endl; cout << LowIndexOf<double, UnuniqueList>::index <<endl; } /* 4 char unsigned char signed char wchar_t 0 2 3 0 1 3 */