首页 文章

实现一个可以存储其函数参数的Functor模板

提问于
浏览
2

我想将任何类型的事件绑定到我正在处理的游戏的(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...) 调用函数时解压缩元组

1 回答

  • 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中实现(并且在该站点上有许多这样的实现) .

相关问题