将可变函数的参数封装在 class 实例中

Encapsulating arguments of variadic function in a class instance

这里有一些有漏洞的代码:

template<typename... Args>
class A 
{

  typedef function_type = void(*)(Args...);

  public:
  void set_args(Args&& ... args)
  {
      // something magic manages to encapsulate
      // args in instance of A
  }
  void apply_args(function_type function)
  {
      // something magic manages to "retrieve"
      // the encapsulated args
      function(std::forward<Args>(args)...);
  }

};

这有可能吗?

你可以利用std::tuple and std::apply

#include <iostream>
#include <tuple>
#include <functional>
#include <string>

template <typename... Ts>
class A
{
    private:
        std::function<void (Ts...)> f;
        std::tuple<Ts...> args;    
    public:
        template <typename F>
        A(F&& func, Ts&&... args)
            : f(std::forward<F>(func)),
              args(std::make_tuple(std::forward<Ts>(args)...))
        {}

        void Invoke()
        {
            std::apply(f, args);
        }
};

template <typename F, typename... Args>
A<Args...> Create(F&& f, Args&&... args)
{
    return A<Args...>(std::forward<F>(f), std::forward<Args>(args)...);
}

int main()
{
    auto helloWorld = Create([] (std::string a, std::string b) { std::cout << a << ", " << b; }, std::string("Hello"), std::string("World!"));

    helloWorld.Invoke();
}

您可以将模板参数存储在 std::tuple type and the use std::apply 的 class 数据成员中,以便将存储的参数应用于提供的函数。

所以,假设你有一个像这样的 Action class:

template <typename... Args>
class Action {
    std::tuple<Args...> args_;

public:
    Action() = default;
    Action(Args&&... args)
        : args_(std::forward<Args>(args)...)
    {}

    void args(Args&&... args) {
        args_ = std::make_tuple<Args...>(std::forward<Args>(args)...);
    }

    template <typename F>
    void apply(F&& fun) {
        std::apply(std::forward<F&&>(fun), args_);
    }
};

通过构造函数 Action action(1, 2, 3); 或通过单独的函数 action.set(3, 2, 1);.

设置参数的位置

那么你的主要功能可以是这样的:

int main() {
    Action action(1, 2);

    action.apply([](int a, int b) {
        std::cout << "a + b = " << (a + b) << std::endl;
    });

    return 0;
}

勾选live example