Typelists(三)
类型排序准则(将最深派生放在最前方)
Typelists3.h
#include "../型别选择/select.h"//for template<class If, class Then, class Else> struct Select; #include "../编译期间侦测可转换性和继承性/Conversion.h"//for #define DERIVE_BASE_CLASS #include "Typelists2.h" //从Tlist中找到T的最深派生类 template<class TList, class T> struct MostDerived; /*****普遍情况*****/ template<class First, class Second, class T> struct MostDerived<TypePair<First, Second>, T> { //Second部分的最深派生类 typedef typename MostDerived<Second, T>::Result Cadidate; //和First比较,取更深的派生类 typedef typename Select<DERIVE_BASE_CLASS(First, Cadidate), First, Cadidate>::Result Result; }; /*****边界情况*****/ //如果是空链表就是它本身 template<class T> struct MostDerived<NullType, T> { typedef T Result; }; //将派生类移动到最前方 template<class TList> struct DeriveToFront; /*****普遍情况*****/ template<class First, class Second> struct DeriveToFront<TypePair<First, Second>> { //找到First的最深继承子类 typedef typename MostDerived<Second, First>::Result DerivedClass; //替换在Second中替换这个类 typedef typename Replace<Second, DerivedClass, First>::Result NewSecond; //生成新的结果 typedef TypePair<DerivedClass, NewSecond> Result; }; /*****边界情况*****/ template<> struct DeriveToFront<NullType> { typedef NullType Result; };
Typelists3.cpp
#include <iostream> using namespace std; #include "Typelists3.h" struct Base{}; struct DeriveA:Base{}; struct DeriveB:Base{}; struct DeriveBA:DeriveB{}; int main() { typedef Typelists_4(Base, DeriveA, DeriveB, DeriveBA) OriginalList; cout << typeid(TypeAt<OriginalList, 0>::Result).name() << endl; cout << typeid(TypeAt<OriginalList, 1>::Result).name() << endl; cout << typeid(TypeAt<OriginalList, 2>::Result).name() << endl; cout << typeid(TypeAt<OriginalList, 3>::Result).name() << endl << endl; //2005的傻子编译器对后者会给出报错 /*static_cast<unsigned>(Conversion<Base*, const DeriveA*>::exist && !Conversion<DeriveA*, const void*>::sameType); unsigned(Conversion<Base*, const DeriveA*>::exist && !Conversion<DeriveA*, const void*>::sameType);*/ typedef DeriveToFront<OriginalList>::Result CurrentList; cout << typeid(TypeAt<CurrentList, 0>::Result).name() << endl; cout << typeid(TypeAt<CurrentList, 1>::Result).name() << endl; cout << typeid(TypeAt<CurrentList, 2>::Result).name() << endl; cout << typeid(TypeAt<CurrentList, 3>::Result).name() << endl << endl; } /* struct Base struct DeriveA struct DeriveB struct DeriveBA struct DeriveBA struct DeriveA struct DeriveB struct Base */