实现部分
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
*/