万能函数注册(最终版)

这是我上周不断学习后,所做任务的最终版,虽然没有考虑不类外函数,和类型退化,但大致的功能已经可以实现了。

#include<iostream>
#include <functional>
#include <string>
#include <map>
#include <memory>
#include <typeinfo>
#include <type_traits>
#include <list>
#include <vector>
#include <tuple>
using namespace std;


struct Obj {
	 Obj(int o) : obj(o) {}
	 Obj(const Obj& o):obj(o.obj){}
	 Obj(Obj&& o) {
		obj = o.obj;
		o.obj = 0;
	}
	int obj; // 0 for undefined; not 0 valid
};

template <typename Dst, typename Src>	//函数地址转换
Dst union_cast(Src s) {
  union {
    Src ss;
    Dst dd;
  };
  ss = s;
  return dd;
}

class Base{	//抽象类 其主要作用是为其子类(模板)提供接口
public :
	Base(){
	}
	virtual Base* type() = 0;
	virtual ~Base(){
	}
};

template<typename Ret,typename...Args>	//类模板 且用父类 
class Derived : public Base{
public :
	function<Ret(Args...)> fun ;	//function函数类 用于保存对象
	uint64_t add_fun;
public :
	Derived(function<Ret(Args...)> f,u_int64_t add_fun):fun(f),add_fun(add_fun){	//用function来接收lambda表达式
	}
	Base* type(){
		return this;
	}
	~Derived(){
	}
};

class function_factory{
private:
	map<string,list<unique_ptr<Base> > > mslu;
public :
	function_factory() = default;

/**************************************		函数注册	*****************************************/

	template<typename Ret,class C,typename... Args>
	bool register_function(const string& k,Ret (C::*f)(Args...args),C *obj){	//函数注册
		u_int64_t add_fun = union_cast<u_int64_t>(f);
		auto fun = [f,obj](Args...args)->Ret {	//lambda
			return (obj->*f)(args...);
		};
		if(mslu[k].size() == 0){		//如果不存在,可以往名为string的list中保存这个函数
			mslu[k].push_front(unique_ptr<Base>(new Derived<Ret,Args...>(fun,add_fun)));
		}else{
			list<unique_ptr<Base> >::iterator it = mslu[k].begin();
			for(;it != mslu[k].end();it++){		//遍历容器,是否已存在相同的函数
				Derived<int,Args...> *d = (reinterpret_cast<Derived<int,Args...>* >(it->get()));
				if(add_fun == d->add_fun){	//如果相同,则说明有相同的函数
				cout << "failed to register the function!!!" << endl;
					return false;
				}
			}
			mslu[k].push_front(unique_ptr<Base>(new Derived<Ret,Args...>(fun,add_fun)));
		}
		cout << k << ":success to register function..." << endl;
		return true;
	}

	/*************************************		函数调用	********************************************/


	template <int a,typename Fun,typename Head,typename...Args>
	struct Count {
	static inline int Run(Fun fun,Head head,Args...args){
		return Count<a-1,Fun,Head,Args...>::Run(fun,args...,head);
	}
	};

	template <typename Fun,typename Head,typename...Args>
	struct Count<0,Fun,Head,Args...> {
	static inline int Run(Fun fun,Head head,Args...args){ 
		return fun(head,args...);
	}
	};

	//参数包展开 
	template<typename FUNC,typename HEAD,typename...Args>
	int deal(FUNC func,HEAD&& head,Args&&...args){
		return Count<sizeof...(args)+1,FUNC,HEAD,Args...>::Run(func,head,args...);
	}

	template<typename...Args>
	vector<int> call(const string k,Args&&...args){		//函数调用
		vector<int> v;
		list<unique_ptr<Base> >::iterator it = mslu[k].begin();
		cout << k <<" size:" << mslu[k].size() << endl;
		for(;it != mslu[k].end();it++){
			if(typeid(*(*it)->type()) != typeid(Derived<int,Args...>)){		//需要用 decay 进行类型退化 
			//	throw string("there are different!!!");
			}
			Derived<int,Args...> * d = (reinterpret_cast<Derived<int,Args...> *>(it->get()));//重解释 不进行编译期的类型检查
			v.push_back(deal(d->fun,forward<Args>(args)...));
			/*
				2.得是移动语义(只考虑是否为右值引用)
				都得满足,否则就得抛出异常
			*/
		}
		return v;
	}
};

struct A {
	int add(int a,int b){
		return a + b;
	}
};

struct B{
	int mutiply(int a,int b,int c){
		return a * b * c;
	}
};


struct C{
	int value(Obj& o){
		return o.obj;
	}
};


struct D{
	int value(Obj& o) {
		o.obj = 3;
		return o.obj;
	}
};

int main(){
	function_factory fac;
	A aa;
	C cc;
	D dd;
	fac.register_function<int,A>("add",&A::add,&aa);
	fac.register_function<int,A>("add",&A::add,&aa);	//验证是否能够添加成功
	fac.register_function<int,C>("value",&C::value,&cc);
	fac.register_function<int,D>("value",&D::value,&dd);
	cout << "******************************" << endl;
	try{
		int a = 2;
		const int b = 2;
		Obj obj1(1);
		vector<int> v =  fac.call<>("value",Obj(1));	//Obj(1)
		fac.call<>("value", obj1);
		cout << "++++++++++++++++++++ " << obj1.obj << endl;
		vector<int> v1 = fac.call<>("add",1,3);
		cout << "--------------------" << endl;
		cout << "add" << endl;
		cout << v1.at(0) << endl;
		cout << "--------------------" << endl;
		cout << "value" << endl;
		cout << v.front() << endl;
		cout << v.at(1) << endl;
		cout << "--------------------" << endl;
	}catch(string& s){
		cout << s << endl;
	}catch(...){
		cout << "failed" << endl;
	}
	cout << "*************************" << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值