C++中如何自己封装一个Callable

文章介绍了如何在脚本语言中实现动态注册C++类方法,使用std::any存储参数,模板ClassMethod封装类方法调用,并处理类型转换和参数匹配问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求背景

有时候静态编译太不灵活,我们需要更灵活的运行时操作。

又或真假设你在开发一个脚本,想注册本地的C++函数到脚本语言的标准库中。例如gdscript的Callable。

下面是一个我的一个简单的实现。我们假设脚本语言中的变量类型是std::any。根据情况不同实现细节也可能不同。

实现

首先我们需要对可调用对象进行一个抽象的表示。

struct Callable {
  int _argc = 0;
  virtual std::any call(const std::vector<std::any>& args) = 0;
  virtual ~Callable() = default;
};	

很简单,定义一个抽象方法call,参数列表使用vector<any>来表示,。然后用argc表示这个可调用的对象可接收多少个参数。

类方法

这里仅仅实现一个比较复杂的可调用对象,类方法。这是我们准备的测试类。

struct Foo {
  int a = 10;
  int foo(int n, char ch, const std::string* msg)
  {
	  a += n;
	  cout << ch << ": " << *msg << a << endl;
	  return a;
  }
  int bar(int n)
  {
	  cout << "--" << n << "--" << endl;
	  return n;
  }
};

应当注意的是,类方法并不能简单的转换为函数指针。

比如上述的bar的类型不是int(*)(int),而是int(Foo::*)(int)。应当注意这点。随后我们继承这个Callable,一个名为ClassMethod的类来包装类方法。这里我们实现了使用了和std::functional差不多的形式。为了表达直观,我们用类似ClassMethod<ClassName, int(int)>这样的形式,而不是ClassMethod<int,int>这样的形式。

template<typename... Args>
struct ClassMethod;		//永远也不会匹配到这个模板,所以不用定义。

template<typename ClassName, typename Ret, typename ... Args>
struct ClassMethod<ClassName, Ret(Args...)> : public Callable {/*TODO*/}

//使用方式
<ClassMethod<Foo, int(int, char, const std::string*)>> callable;

Ret表示返回值,Args表示一个参数包,也就是参数的类型列表。后续我们使用包展开来对其进行操作。

ClassMethod内部:

  static con
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值