/******************************************************************** author : Clark/陈泽丹 created : 2014-4-22 purpose : 双分派文件 本想用暴力模板双分派解决就好了,因为类型不过五六个,但每每动笔时就有一个 幽灵般的声音在回荡:暴力法的遍历开销XXX... 这个声音谁发的?呃,你懂的。 纠结一会后决定还是费力点用map表解决算了,毕竟这是服务器,能省开销就省些吧。 其实就这种查多删少的操作,还可以用SortedVector类再进一步压榨性能。 但想想哥只是个写脚本的,还是老实点好... *********************************************************************/ #pragma once #include <map> #include <algorithm> using namespace std; template< class _SIGN, class _BL, class _BR > class CommonDispatcher { public: virtual ~CommonDispatcher() { auto Clear = []( pair<KEY_TYPE const, FunImpl*> _item ) -> void { if( NULL != _item.second ) { delete _item.second; _item.second = NULL; } }; for_each( m_dispatch_map.begin(), m_dispatch_map.end(), Clear ); m_dispatch_map.clear(); } //注册功能 template< int _L, int _R, class _Fun > void Regist( const _Fun& _fun ) { class Adapter: public FunImpl { public: Adapter(const _Fun& _fun):fun(_fun){} virtual void operator()( _BL *_pl, _BR *_pr ) { fun( _pl, _pr ); } private: _Fun fun; }; KEY_TYPE key = make_pair(_L,_R); m_dispatch_map[key] = new Adapter(_fun); } //派发 void operator()( _BL *_pl, _BR *_pr ) { if( NULL != _pl && NULL != _pr ) { KEY_TYPE key = make_pair(_pl->GetType(),_pr->GetType()); auto it = m_dispatch_map.find( key ); if( m_dispatch_map.end() != it ) { int k = 0; (*(it->second))(_pl,_pr); } } } private: struct FunImpl { virtual void operator()( _BL *_pl, _BR *_pr ) = NULL; }; typedef pair<long,long> KEY_TYPE; map< KEY_TYPE, FunImpl* > m_dispatch_map; };
struct BaseMoveRune{}; struct BaseL { virtual long GetType(){ return 2; } }; struct BaseR { virtual long GetType(){ return 2; } }; struct Test { void operator()( BaseL* _pl, BaseR *_pr ) { int k = 0; } };
CommonDispatcher< BaseMoveRune, BaseL, BaseR > m_dispatcher; Test test; m_dispatcher.Regist<1,2>(test); BaseL l; BaseR r; m_dispatcher( &l, &r );