这次优化了函数调用call函数,增加复用性,不过我依然没有写类外函数的情况,大家可以自己考虑
#include<iostream>
#include <functional>
#include <string>
#include <map>
#include <memory>
#include <typeinfo>
using namespace std;
class Base{ //抽象类 其主要作用是为其子类(模板)提供接口
public :
Base(){
}
virtual ~Base(){
}
};
template<typename Ret,typename...Args> //类模板 且用父类
class Derived : public Base{
public :
function<Ret(Args...)> fun; //function函数类 用于保存对象
public :
Derived(function<Ret(Args...)> f):fun(f){ //用function来接收lambda表达式
}
~Derived(){
}
};
class function_factory{
private:
map<string,unique_ptr<Base> > m; //每一个string对应一个函数,
public :
template<typename Ret,class C,typename... Args>
bool register_function(const string& k,Ret (C::*f)(Args...),C *obj){ //函数注册
if(m[k] != nullptr){ //判断该函数对应的名字是否已被使用
return false;
}
auto fun = [f,obj](Args...args)->Ret { //lambda
(obj->*f)(args...);
};
m[k] = make_unique<Derived<Ret,Args...> >(fun); //保存函数
return true;
}
/* 能实现功能
template<typename Ret,typename T,class C,typename...Args>
Ret call(const string& k,Args...args){
Derived<T,C,Args...> d = (dynamic_cast<Derived<T,C,Args...>& >(*m[k]));
return d.fun(d.obj,args...);
}
*/
template<typename...Args>
int call(const string& k,Args...args){ //函数调用
Derived<int,Args...> d = (dynamic_cast<Derived<int,Args...>& >(*m[k]));//下行转换
return d.fun(args...);
}
};
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;
}
};
int main(){
function_factory fac;
A aa;
fac.register_function<int,A>("add",&A::add,&aa);
//cout << fac.call<int,int,A>("add",9,10) << endl;
cout << fac.call<>("add",1,2) << endl;
cout << "---------------------" << endl;
B bb;
fac.register_function<int,B>("mutiply",&B::mutiply,&bb);
cout << fac.call<>("mutiply",1,2,3) << endl;
return 0;
}