gpt4 book ai didi

c++ - 如何合法地将函数指针转换为方法指针?

转载 作者:行者123 更新时间:2023-12-02 10:03:14 26 4
gpt4 key购买 nike

我正在寻找 std::mem_fn 的反义词: 将函数指针转换为成员指针(例如 void(*)(C*)void(C::*)() 对于给定的 C 类)。

背景

我正在使用第 3 方库(例如 lib1.h)为另一个第 3 方库(lib2.h)创建绑定(bind)。

lib1.h 中的一些函数接收指向接受 Value 的方法的方法指针。参数(也在 lib1.h 中定义)。另一方面,lib2.h 类不包含此类方法,因此我必须通过 lambda 函数手动进行包装:

/* lib1.h (can't touch this) */ 
class Value;
class Property;

template <typename C>
struct ObjectWrap {
using Method = void(C::*)(Value);
static Property declare(std::string name, Method method);
};

/* lib2.h (can't touch this) */
struct Person {
void greet(std::string name);
};

/* bindings.cpp */
std::string value_to_std_string(Value v);

Property declarePersonGreet() {
return ObjectWrap<Person>::declare("greet",
/* ERROR */ [](Person* p, Value v) {
p->greet(value_to_std_string(v));
});
}

我相当有信心我没有滥用 lib1.h 的 API(不幸的是,通过派生 lib2.h 的类来实现这些方法不是一种选择)。因此,我觉得转换为方法指针是唯一的解决方案。

有没有任何合法的方法可以做到这一点?如果可能,我想避免未定义的行为。

最佳答案

不,你不能做这样的 Actor 。即使你能得到 void(Person::*)(Value) ,您不能使用它,因为 Person没有这种方法。如果 lib1 需要类型 C带有成员函数 void(C::)(Value)那么就没有办法提供这种类型 C用相应的方法。您可以为 Person 编写一个包装器:

struct Wrapper {    
Person p;
void greet(Value v) {
p.greet(value_to_std_string(v));
}
};


Property declarePersonGreet() {
return ObjectWrap<Wrapper>::declare("greet",&Wrapper::greet);
}

如果您有许多类似于 Person 的类您可以将包装器设为模板:
template <typename T>
struct Wrapper {
T p;
void greet(Value v) {
p.greet(value_to_std_string(v));
}
};

...可能还对要在包装对象上调用的成员函数和要用于转换参数的函数进行参数化。

关于c++ - 如何合法地将函数指针转换为方法指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61503822/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com