根据评论,您可以使用std::function
或类似于所提议的结构here http://blog.molecular-matters.com/2011/09/19/generic-type-safe-delegates-and-events-in-c/.
它遵循第二个建议的最小可行示例:
class Dispatcher {
Dispatcher() { }
template<class C, void(C::*M)() = C::receive>
static void invoke(void *instance) {
(static_cast<C*>(instance)->*M)();
}
public:
template<class C, void(C::*M)() = &C::receive>
static Dispatcher create(C *instance) {
Dispatcher d;
d.fn = &invoke<C, M>;
d.instance = instance;
return d;
}
void operator()() {
(fn)(instance);
}
private:
using Fn = void(*)(void *);
Fn fn;
void *instance;
};
struct S {
void receive() { }
};
int main() {
S s;
Dispatcher d = Dispatcher::create(&s);
d();
};
请注意,它必须根据您的要求进行相应修改(目前,目标成员方法没有返回值并且不接受参数)。
此外,它可以轻松扩展以存储目标成员方法的数组,这就是您所寻找的:只需存储成对的向量instance
s and invoke
功能。
此外,您可以将可变参数模板与Dispatcher
功能使其更加灵活。这样,您就可以定义Dispatcher
具有不同的返回类型和参数列表。
EDIT
它遵循一个示例Dispatcher
接受多个目标成员函数。
通过如上所述的可变参数模板来扩展它仍然很容易。
#include <vector>
#include <utility>
class Dispatcher {
template<class C, void(C::*M)() = C::receive>
static void invoke(void *instance) {
(static_cast<C*>(instance)->*M)();
}
public:
template<class C, void(C::*M)() = &C::receive>
void bind(C *instance) {
auto pair = std::make_pair(&invoke<C, M>, instance);
targets.push_back(pair);
}
void operator()() {
for(auto pair: targets) {
(pair.first)(pair.second);
}
}
private:
using Fn = void(*)(void *);
std::vector<std::pair<Fn, void*>> targets;
};
struct S {
void receive() { }
};
struct T {
void receive() { }
};
int main() {
S s;
T t;
Dispatcher d;
d.bind(&s);
d.bind(&t);
d();
};
请注意,在上面的示例中,不能保证提交的指针为instance
一旦实际使用仍然有效。您应该关注绑定对象的生命周期,或者稍微修改示例以引入更安全的句柄。