在类实例中封装可变参数的参数

问题描述 投票:2回答:3

这里有一些带孔的代码:

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)...);
  }

};

以某种方式可能吗?

c++ parameter-passing function-pointers variadic-functions
3个回答
0
投票

是的,有可能。为了存储参数,您需要std::tuple和进行调用std:: apply


0
投票

您可以使用std::tuplestd::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();
}

-1
投票

您可以将模板参数存储在std::tuple类型的类数据成员中,并可以使用std::tuple来将存储的参数应用于所提供的函数。

所以,假设您有一个像这样的std::apply类:

std::apply

您通过构造函数Action或通过单独的函数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);

© www.soinside.com 2019 - 2024. All rights reserved.