我想将任何类型的事件绑定到我正在处理的游戏的(G)UI系统的任何类型的函数。
我想将任何类型的函数及其初始参数存储在Functor模板类中,我可以将其绑定到信号绑定索引。绑定到信号绑定的事件一旦出现在事件队列中就会触发它,这将导致绑定到此绑定的所有Functors被调用。
我发现存储函数参数的方法是在函子模板中使用std::tuple
,但我需要帮助正确初始化它并在调用函数时正确解压缩。
这是我到目前为止所做的:
template<typename R, typename... Args>
class FuncBinding {
private:
std::tuple<Args...> args;
R(*fun)(Args...);
public:
FuncBinding(R(*pF)(Args...) , Args... pArgs)
:fun(pF), args(std::make_tuple<Args...>(pArgs)) {}
R invoke() {
return fun(args...);
}
R callFunc(Args... pArgs) {
return fun(pArgs...);
}
};
如何正确使用参数包Args
以便......
std::tuple<Args...>
std::tuple<Args...>
实例args
R(*fun)(Args...)
答案 0 :(得分:3)
从初始化的角度来看,tuple
只是另一个类类型,所以你只需将包传递给它的构造函数来初始化它:
FuncBinding(R(*pF)(Args...) , Args... pArgs)
: fun(pF), args(pArgs...)
{ }
或者,更有效率:
args(std::forward<Args>(pArgs)...)
如果某些forward
是左值引用类型,我使用std::move()
代替Args...
。
在调用方面,有一个名为std::apply()
的C ++ 17函数可以满足您的需求:
R invoke() {
return std::apply(fun, args);
}
它可以在C ++ 11中实现。 cppreference页面包含一个涉及std::make_index_sequence
的实现,它本身可以在C ++ 11中实现(并且在这个站点上有很多这样的实现)。