实现C++双分派

/********************************************************************
 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 );

你可能感兴趣的:(实现C++双分派)