c++ - 将模板可变参数函数及其参数传递给函数

标签 c++ variadic-templates std-function template-argument-deduction stdbind

我希望能够传递一个函数,该函数接受任意数量的参数,加上匹配的参数,作为函数的参数。到目前为止,这是我尝试过的方法,我迷路了,因为我不太了解参数包的工作原理。

template <class T, typename... Args>
static void BindAction(const std::string& name, T* owner, const std::function<void(T*, Args...)>& func, Args... args)
{
    for (InputAction& action : m_actions)
        if (action.m_name == name)
            action.BindFunction(std::bind(func, owner, args...));
}

我用这些测试它:

void Test(float f, std::string s, int i);

BindAction<Simulation>("Test", this, &Simulation::Test, 5.f, "a string", 2);

错误只是函数模板“BindAction()”的实例与参数列表不匹配。

请不要通过告诉我调用 std::bind() 然后将结果函数作为参数传递来简化问题。我真的希望电话是这样的。如果这不可能,那就太糟糕了,但只有到那时我才会检查其他解决方案。

最佳答案

您绑定(bind)了所有参数,因此您的 map 实际上将充满 std::function<void()> ,它不会匹配传入的函数。您可以将 lambda 与 std::invoke 结合使用为了获得更可预测的结果,只需使用模板来推断传入的可调用对象的类型:

#include <functional>
#include <iostream>

class Actions {
 public:
  template <typename F, typename... Args>
  void BindAction(const std::string& name, F f, Args... args) {
    actions_.emplace(
      name,
      [f, args...] () mutable { return std::invoke(f, args...); }
    );
  }

  void call(const std::string& name) {
    actions_[name]();
  }

 private:
  std::unordered_map<std::string, std::function<void()>> actions_;
};

还有一个简单的使用示例:

class Cls {
  public:
    void do_func(int i) {
      std::cout << "Cls::do_func(" << i << ")\n";
    }
};

int main() {
  Cls c;
  Actions actions;
  actions.BindAction("test", &Cls::do_func, c, 1);
  actions.call("test");
}

关于c++ - 将模板可变参数函数及其参数传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54855020/

相关文章:

c++ - 如何在 C++ 中遍历类的公共(public)变量?

c++ - std::function 作为模板参数

c++ - 制作一个指向两个函数的 std::function c++

c++ - 用于存储通用 lambda 的通用 std::function

c++ - 为什么仅函数模板的模板参数推导/替换失败?

c++ - 如何访问特征向量矩阵< float, 2, 1 >

c++ - 获取范围内声明的所有变量 - C++

c++可能的空指针取消引用

c++ - 结构化绑定(bind)宽度

c++ - 可变参数模板的类型推导