C++ 任何类成员函数类型
我的最终目标是什么? 我希望库的用户能够指定任意字段名的映射以及与这些字段名关联的成员函数指针。例如:C++ 任何类成员函数类型,c++,c++17,C++,C++17,我的最终目标是什么? 我希望库的用户能够指定任意字段名的映射以及与这些字段名关联的成员函数指针。例如: class-Foo{ 私人: int字段_1_; 双场_2_; 公众: int field_1()常量{return field_1_;} 双字段_2()常量{返回字段_2_;} }; 标准::映射字段={ {“field_1”,&Foo::field_1}, {“field_2”,&Foo::field_2} }; 正如您可能看到的,问题在于成员函数签名可能不同 我试过什么? 我尝试创建
class-Foo{
私人:
int字段_1_;
双场_2_;
公众:
int field_1()常量{return field_1_;}
双字段_2()常量{返回字段_2_;}
};
标准::映射字段={
{“field_1”,&Foo::field_1},
{“field_2”,&Foo::field_2}
};
正如您可能看到的,问题在于成员函数签名可能不同
我试过什么?
我尝试创建any\u mem\u fn
类来存储任何成员函数指针。类的外观如下所示:
class any\u mem\u fn{
结构基础\u成员\u fn\u ptr{
虚拟~base_mem_fn_ptr(){}
虚拟双运算符()(Foo&Foo)=0;
};
模板
结构mem_fn_ptr:base_mem_fn_ptr{
F fn;
成员(F&F)
:fn(标准::正向(f))
{}
双运算符()(Foo&Foo)重写{
返回std::invoke(fn,foo);
}
};
公众:
any_mem_fn():fn_(nullptr){}
any_mem_fn(any_mem_fn&&rhs)=默认值;
any_mem_fn(any_mem_fn const&rhs)=默认值;
模板
任何成员(F&F){
fn=std::使共享(std::转发(f));
}
any_mem_fn&operator=(any_mem_fn&rhs)=默认值;
any_mem_fn&operator=(any_mem_fn const&rhs)=默认值;
~any_mem_fn()=默认值;
模板
双值(T&&obj){
返回std::invoke(*fn_,obj);
}
私人:
std::共享\u ptr fn;
};
在这里,您可以看到,我使用多态性进行类型擦除。此外,您可能会注意到,在每个函数签名返回双精度的情况下,operator()
。这是故意的,目前不是我的问题,所以请不要提及这一点
现在,上面这节课有什么问题。。。问题是它只适用于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_;
};
class any\u mem\u fn{
公众:
模板
任何成员(Ret(C::*m)(){
fn_u=[m](std::any a){return(std::any_cast(a)。*m)(;};
}
//可能为const/volatile组合提供重载,引用。。。
模板
双值(T obj){返回fn_j(obj);}
私人:
std::函数fn_2;;
};
不确定它是否是您想要的,但使用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_;
};
class any\u mem\u fn{
公众:
模板
任何成员(Ret(C::*m)(){
fn_u=[m](std::any a){return(std::any_cast(a)。*m)(;};
}
//可能为const/volatile组合提供重载,引用。。。
模板
双值(T obj){返回fn_j(obj);}
私人:
std::函数fn_2;;
};
您所描述的“目标”是针对给定问题的技术解决方案的一部分。但是我不知道你的代码应该解决哪个问题。对我来说,这感觉像一个XY问题!我看不到任何用例,其中映射存储所有可能的成员函数指针和对象,并在不知道返回类型的情况下调用它们。在prog中会有一个点,我们必须处理返回类型,我们必须知道它代表什么以及它有什么类型。我相信你的想法是错误的@克劳斯如果你想看看我的库,你可能会更清楚我想要实现什么。
std::function
?使用std::tuple
而不是std::map
@Jarod42你能进一步解释一下std::function
有什么帮助吗?你所说的“目标”是什么是给定问题的技术解决方案的一部分。但是我不知道你的代码应该解决哪个问题。对我来说,这感觉像一个XY问题!我看不到任何用例,其中映射存储所有可能的成员函数指针和对象,并在不知道返回类型的情况下调用它们。在prog中会有一个点,我们必须处理返回类型,我们必须知道它代表什么以及它有什么类型。我相信你的想法是错误的@克劳斯如果你想看看我的库,你可能会更清楚我想要实现什么。std::function
?使用std::tuple
而不是std::map
@Jarod42你能进一步解释一下std::function
有什么帮助吗?这正是我需要的。非常感谢你!这正是我需要的。非常感谢你!