实现一个可以存储函数参数的仿函数模板
Implementing a Functor Template which can store its function's arguments
我想将任何类型的事件绑定到我正在开发的游戏的 (G)UI 系统的任何类型的函数。
我想在 Functor 模板 class 中存储任何类型的函数及其初始参数,我可以将其绑定到信号绑定索引。绑定到信号绑定的事件一旦出现在事件队列中就会触发它,这将导致调用绑定到该绑定的所有 Functor。
我发现存储函数参数的方法是在仿函数模板中使用 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
以便...
- ...适当地创建模板class
std::tuple<Args...>
- ...用函子参数
初始化std::tuple<Args...>
实例args
- ...通过函数指针调用函数时解包元组
R(*fun)(Args...)
从初始化的角度来看,tuple
只是另一种 class 类型,因此您只需将 pack 传递给其构造函数即可对其进行初始化:
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 中实现(并且此站点上有许多此类实现)。
我想将任何类型的事件绑定到我正在开发的游戏的 (G)UI 系统的任何类型的函数。
我想在 Functor 模板 class 中存储任何类型的函数及其初始参数,我可以将其绑定到信号绑定索引。绑定到信号绑定的事件一旦出现在事件队列中就会触发它,这将导致调用绑定到该绑定的所有 Functor。
我发现存储函数参数的方法是在仿函数模板中使用 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
以便...
- ...适当地创建模板class
std::tuple<Args...>
- ...用函子参数 初始化
- ...通过函数指针调用函数时解包元组
R(*fun)(Args...)
std::tuple<Args...>
实例args
从初始化的角度来看,tuple
只是另一种 class 类型,因此您只需将 pack 传递给其构造函数即可对其进行初始化:
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 中实现(并且此站点上有许多此类实现)。