C++ 指向具有匹配函数签名的任何 class 的成员函数的指针
C++ Pointer to a member function of any class with matching function signatures
如何将具有相同签名但来自不同 类 的非静态成员函数的引用分配给具有匹配签名的函数指针?
我可以借助 C++ std 库中的 std::function
来完成此操作。我也一直使用常规 C 函数来执行此操作,并且没有来自 std 库的帮助。我正在编写固件和代码-space 是有限的。如果来自 C++ std 库的助手可以做到这一点,那么肯定可以使用纯 C/C++ 语言结构(首选 C++11 之前)手动完成。
展示我意图的示例代码:
class A {
public:
void ping_event_handler();
};
class B {
public:
void ping_event_handler();
};
void A::ping_event_handler_A() {
// Handle ping event in A...
}
void B::ping_event_handler_B() {
// Handle ping event in B...
}
void ping_event_handler_C() {
// Handle ping event in normal function...
}
int main() {
// Ping event "pointer to a function that takes no arguments"
void (*ping_event)();
A a();
B b();
ping_event = a.ping_event_handler; // Attach class A's handler
ping_event(); // Trigger event
ping_event = b.ping_event_handler; // Attach class B's handler
ping_event(); // Trigger event
ping_event = ping_event_handler; // Attach non-class handler
ping_event(); // Trigger event
}
老方法是用函数
传递一个userData
void (*ping_event)(void* userData);
并保存函数和用户数据。
然后在用户端,将 userData 投射到其中 class 并从中调用任何方法:
struct my_function
{
my_function(void (*f)(void*), void* userData) : mF(f), mUserData(userData)
{}
void set(void (*f)(void*), void* userData)
{
mF = f;
mUserData = userData;
}
void operator() () {
mF(mUserData);
}
void (*mF)(void*);
void* mUserData;
};
并在呼叫站点:
template <typename C, void (C::*m)()>
void my_func_helper(void* userData)
{
C* c = static_cast<C*>(userData);
(c->*m)();
}
int main()
{
A a;
my_function f(&my_func_helper<A, &A::ping_event_handler>, &a);
f();
B b;
f.set(&my_func_helper<B, &B::ping_event_handler>, &b);
f();
f.set(ping_event_handler_c, NULL);
f();
}
如何将具有相同签名但来自不同 类 的非静态成员函数的引用分配给具有匹配签名的函数指针?
我可以借助 C++ std 库中的 std::function
来完成此操作。我也一直使用常规 C 函数来执行此操作,并且没有来自 std 库的帮助。我正在编写固件和代码-space 是有限的。如果来自 C++ std 库的助手可以做到这一点,那么肯定可以使用纯 C/C++ 语言结构(首选 C++11 之前)手动完成。
展示我意图的示例代码:
class A {
public:
void ping_event_handler();
};
class B {
public:
void ping_event_handler();
};
void A::ping_event_handler_A() {
// Handle ping event in A...
}
void B::ping_event_handler_B() {
// Handle ping event in B...
}
void ping_event_handler_C() {
// Handle ping event in normal function...
}
int main() {
// Ping event "pointer to a function that takes no arguments"
void (*ping_event)();
A a();
B b();
ping_event = a.ping_event_handler; // Attach class A's handler
ping_event(); // Trigger event
ping_event = b.ping_event_handler; // Attach class B's handler
ping_event(); // Trigger event
ping_event = ping_event_handler; // Attach non-class handler
ping_event(); // Trigger event
}
老方法是用函数
传递一个userData
void (*ping_event)(void* userData);
并保存函数和用户数据。 然后在用户端,将 userData 投射到其中 class 并从中调用任何方法:
struct my_function
{
my_function(void (*f)(void*), void* userData) : mF(f), mUserData(userData)
{}
void set(void (*f)(void*), void* userData)
{
mF = f;
mUserData = userData;
}
void operator() () {
mF(mUserData);
}
void (*mF)(void*);
void* mUserData;
};
并在呼叫站点:
template <typename C, void (C::*m)()>
void my_func_helper(void* userData)
{
C* c = static_cast<C*>(userData);
(c->*m)();
}
int main()
{
A a;
my_function f(&my_func_helper<A, &A::ping_event_handler>, &a);
f();
B b;
f.set(&my_func_helper<B, &B::ping_event_handler>, &b);
f();
f.set(ping_event_handler_c, NULL);
f();
}