https://blog.csdn.net/xiaodan007/article/details/24340983
- /********************************************************************
- 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 );