c++ - 任何类成员函数类型
问题描述
我的最终目标是什么?
我希望我的库的用户能够指定任意字段名称的映射以及与这些字段名称关联的成员函数指针。一个例子如下:
class Foo {
private:
int field_1_;
double field_2_;
public:
int field_1() const { return field_1_; }
double field_2() const { return field_2_; }
};
std::map<std::string, any_mem_fn> fields = {
{ "field_1", &Foo::field_1 },
{ "field_2", &Foo::field_2 }
};
如您所见,问题在于成员函数签名可能不同。
我试过什么?
我尝试创建any_mem_fn
存储任何成员函数指针的类。类如下所示:
class any_mem_fn {
struct base_mem_fn_ptr {
virtual ~base_mem_fn_ptr() {}
virtual double operator()(Foo& foo) = 0;
};
template <typename F>
struct mem_fn_ptr : base_mem_fn_ptr {
F fn;
mem_fn_ptr(F&& f)
: fn(std::forward<F>(f))
{}
double operator()(Foo& foo) override {
return std::invoke(fn, foo);
}
};
public:
any_mem_fn() : fn_(nullptr) {}
any_mem_fn(any_mem_fn&& rhs) = default;
any_mem_fn(any_mem_fn const& rhs) = default;
template <typename F>
any_mem_fn(F&& f) {
fn_ = std::make_shared<mem_fn_ptr<F>>(std::forward<F>(f));
}
any_mem_fn& operator=(any_mem_fn&& rhs) = default;
any_mem_fn& operator=(any_mem_fn const& rhs) = default;
~any_mem_fn() = default;
template <typename T>
double value(T&& obj) {
return std::invoke(*fn_, obj);
}
private:
std::shared_ptr<base_mem_fn_ptr> fn_;
};
在这里,如您所见,我使用多态性进行类型擦除。此外,您可能会注意到,operator()
如果每个函数签名都返回double
. 这是故意的,目前不是我的问题,所以请不要参考这个。
现在,上面的类有什么问题......问题是它只适用于Foo
类的成员函数。如果我尝试存储Bar
类的成员函数,上面的代码将不起作用。为了使上述代码在任何类的情况下都能正常工作,我需要operator()
为每个我不能做的特定类重载,因为我的库不知道库用户拥有的所有类。
完整的演示在这里。
我正在研究的图书馆在这里。
问题:是否有可能以某种方式将任何类成员函数存储在一个类中,并能够稍后在对象上调用该成员函数?
解决方案
不确定这是您想要的,但使用 std::function 和 std::any,您可能会执行以下操作:
class any_mem_fn {
public:
template <typename Ret, typename C>
any_mem_fn(Ret (C::*m)()) {
fn_ = [m](std::any a) { return (std::any_cast<C>(a).*m)(); };
}
// Possibly provide overloads for combination const/volatile, reference...
template <typename T>
double value(T obj) { return fn_(obj); }
private:
std::function<double(std::any)> fn_;
};
推荐阅读
- javascript - 将对象值传递到事件侦听器范围之外
- reactjs - 根据其他输入 onChange 更改输入值
- discord.js - 如何给所有成员一个角色,有时间间隔
- python - 如何通过列值的条件删除 DataFrame 中的行
- angular - ng-template 中的 *ngif 不起作用 - Angular
- python - Discord.py ping 命令在 cog 中不起作用
- assembly - 所有线程中的 TLS 数据地址相同
- javascript - 为什么 jQuery 选择器 ':not' 不起作用?
- html - 如何在引导程序中制作响应式视频?
- ios - 引发错误时,URLSession.DataTaskPublisher 不发布值