如何制作指向类和成员函数的双指针?
基本上,我有一些(很多)泛型类接受像这样的函数指针:
void Gen::regCallback(void (*callback)(void const *), void const * callbackData)
在课堂上,我经常有这样的功能
void Foo::doSomething(void const * instance) // this one is static
{
auto myself((Foo const *)instance);
myself->...do stuff...
myself->...do stuff...
myself->...do stuff...
}
或方法/功能双胞胎
void Foo::doSomething(void const * instance) // this one is static
{
((Foo const *)instance)->doSomething();
}
void Foo::doSomething() const
{
...do stuff...
...do stuff...
...do stuff...
}
我想以某种方式减少代码中的混乱(通过直接注册成员), 我知道选项:
void Gen::regCallback(void (Foo::*callback)(void const *), Foo const * member);
但我需要将类型(Foo)作为参数传递(即Foo1,Foo2,FooTotallyDifferent)
由于各种原因,我不能将模板用于类类型,所以
template <typedef T>
class Gen
{
void regCallback(void (T::*callback)(void const *), T const * member)
{
...
}
}
对我来说是没有选择
答案 0 :(得分:1)
看起来你想要的是能够注册任何可调用的,它接受零参数并返回void。由于您可能会将这些回调存储在某个地方,因此您还需要类型擦除 - 因为您希望能够非常地调用doSomethingElse()
和Bar::someMethod(with, some, args)
甚至std::function<void()>
。对于所有这些以及更多,有std::function
。特别是在您的情况下,std::function<void()>
。
用法很简单。可以从与该签名匹配的任何函数构造std::function
。下面是一个示例,它将几种不同的可调用类型添加到一个using Callback = std::function<void()>;
std::vector<Callback> callbacks;
void free() { std::cout << "free\n"; }
void free(int arg) { std::cout << "free " << arg << "\n"; }
struct Foo {
void something() const { std::cout << "Foo with " << i << "\n"; }
int i;
};
callbacks.emplace_back(free); // normal function pointer
Foo f;
callbacks.emplace_back(std::bind(&Foo::something, f)); // member function bound to instance, copies f
callbacks.emplace_back([]{ free(42); }); // lambda calling function with specific argument
f.i = 64;
callbacks.emplace_back([&]{ f.something(); }); // captures f
f.i = 72;
// call all of them
for (auto fn : callbacks) {
fn();
}
类型的向量中:
free
Foo with 42
free 42
Foo with 72
那将打印
{{1}}