c++存储任意类型的函数对象和类

目录

任意函数对象

备忘

任意类

备忘

总结


任意函数对象

#include <iostream>
#include <functional>
#include <unordered_map>
#include <string>
#include <any>

using namespace std;

template<class RetType>
concept VoidType = is_void<RetType>::value;

template<class RetType>
concept NoneVoidType = !is_void <RetType>::value;

class BaseService
{
public:
	virtual ~BaseService() {}
	string info;
};

//question: NoneVoidType and VoidType can not used at the mean time
template<NoneVoidType RetType, class... ArgTypes>
class Service : public BaseService
{
	using FuncType = function<RetType(ArgTypes...)>;
public:
	Service(FuncType func)
		:func_(func)
	{

	}
	RetType Run(ArgTypes&&... args)
	{
		return func_(forward<ArgTypes>(args)...);
	}
private:
	FuncType func_;
};

//可变参数无法偏特化
//template<VoidType RetType,class... ArgTypes>
//class Service: public BaseService
//{
//	using FuncType = function<void(ArgTypes...)>;
//public:
//	Service(FuncType func)
//		:func_(func)
//	{
//
//	}
//	void Run(ArgTypes... args)
//	{
//		func_(args...);
//	}
//private:
//	FuncType func_;
//};

class ServiceManager
{
	using BaseServicePtr = shared_ptr<BaseService>;

public:
	template<class ServiceType>
	void RegisterService(const string& name, const ServiceType& service)
	{
		service_map_.insert(pair<string, BaseServicePtr>(name, BaseServicePtr(new ServiceType(service))));
	};

	template<class RetType, class... ArgTypes>
	RetType Excute(const string& name, ArgTypes&&... args)//
	{
		if (service_map_.count(name))
		{
			auto service_ptr = service_map_[name];
			Service<RetType, ArgTypes...>* true_service_ptr = dynamic_cast<Service<RetType, ArgTypes...>*>(service_ptr.get());
			return true_service_ptr->Run(forward<ArgTypes>(args)...);
		}
		else
		{
			return RetType();
		}
	}	
private:
	unordered_map<string, BaseServicePtr> service_map_;
};

struct StatusCode
{
	int code = 0;
	
};

ostream& operator <<(ostream& os, const StatusCode code)
{
	os << "status code: " << code.code << endl;
	return os;
}

int main()
{
	ServiceManager manager;
	auto add = [](int a, double b, double& c)->double
	{
		c = a + b;
		return a + b;
	};
	auto add1 = [](int a, double b, double& c)->StatusCode
	{
		c = a + b;
		return StatusCode{ 0 };
	};
	Service<double, int, double,double&> add_service(add);
	Service<StatusCode, int, double, double&> add1_service(add1);
	manager.RegisterService<Service<double, int, double,double&>>("add", add_service);
	manager.RegisterService<Service<StatusCode, int, double, double&>>("add1", add1_service);
	double test = 0;
	cout<<manager.Excute<double>("add", 2, 1.08,test)<<endl;
	cout << test << endl;

	cout << manager.Excute<StatusCode>("add1", 2, 2.08, test);
	cout << test << endl;

	//any a = 2;
	//any b = 1.08;
	//any c = 0.f;
	//any d = a + b;
	//cout << manager.Excute<double>("add", a, b, c) << endl;
	//cout << any_cast<double>(c) << endl;

	return 0;
}

备忘

&& 加 forward完美转发;

有返回值和无返回值函数没办法用一个类实现,通过额外信息记录。

任意类

class A {
public:
    static A* Create() { return new A(); }
}; 

Instance::Register("A", A::Create);
auto a = Instance::Create("A");

备忘

c++ 无法存储类型,只能存储产生该类型对象的函数;

总结

c++ 没有反射系统,在rpc等场景中需要构建用户级反射系统,以便于存储类型或者函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值