学MCD,用TypeList实现的Visitor
#include <map>
using namespace std;
#define TYPELIST_1(T) TypeList<T,NullType>
#define TYPELIST_2(T1,T2) TypeList<T1,TYPELIST_1(T2) >
class IObject;
typedef void (*ff)(IObject&);
class IDispatcher
{
protected:
map<int,ff> m_map;
public:
ff Do(int t)
{
map<int,ff>::iterator t_iterator=m_map.find(t);
if (t_iterator==m_map.end())
{
MessageBox(NULL,"no find","haha",MB_OK);
return NULL;
}
else
{
return t_iterator->second;
}
};
};
// 每个派生自IObject得m_value都是不同的,用于识别不同的类
class IObject
{
public:
int m_value;
IObject(int t):m_value(t){};
virtual ~IObject(){};
virtual void pp(){};
virtual void view(IDispatcher& dispatcher)
{
ff f=dispatcher.Do(m_value);
if (f)
f(*this);
};
};
class A:public IObject
{
public:
A():IObject(1){};
};
class B:public IObject
{
public:
B():IObject(2){};
};
class C:public IObject
{
public:
C():IObject(3){};
};
template<class T>
struct Type2Type
{
typedef T OriginalType;
};
class NullType;
template<class T,class U>
struct TypeList
{
typedef T Head;
typedef U Tail;
};
typedef TypeList<A,TypeList<B,NullType> > mytypelist;
template<class T>
class FUnit
{};
template<>
class FUnit<A>
{
public:
enum { m_value=1 };
static void DoSomething(IObject& object)
{
MessageBox(NULL,"A:DoSomething","ddd",MB_OK);
};
};
template<>
class FUnit<B>
{
public:
enum { m_value=2 };
static void DoSomething(IObject& object)
{
MessageBox(NULL,"B:DoSomething","ddd",MB_OK);
};
};
template<class TList,template<class> class Unit>
class GH;
template<class T1,class T2,template<class> class Unit>
class GH<TYPELIST_2(T1,T2),Unit>:public GH<T1,Unit>,public GH<T2,Unit>
{
};
//加这个是VS.2003的行为和MCD的有所不同
template<class YT,template<class> class Unit>
class GH<TYPELIST_1(YT,NullType),Unit>:public GH<YT,Unit>,public GH<NullType,Unit>
{
};
template<class YT,template<class> class Unit>
class GH:public Unit<YT>
{
};
template<template<class> class Unit>
class GH<NullType,Unit>
{
};
template<class TList,template<class> class Unit>
class MyDispatcher:public IDispatcher
{
public:
MyDispatcher()
{
DoInsert<TList>();
};
template<typename T>
void DoInsert()
{
pair<int,ff> t_pair(GH<T,Unit>::GH<T::Head,Unit>::m_value,GH<T,Unit>::GH<T::Head,Unit>::DoSomething);
m_map.insert(t_pair);
DoInsert<T::Tail>();
};
template<>
void DoInsert<NullType>()
{
};
//替换DoSomething可以单独和整体。
//..................
};