Search code examples
c++parameter-passingfunction-pointersvariadic-functions

Encapsulating arguments of variadic function in a class instance


Here some code with holes:

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

};

Would that be somehow possible ?


Solution

  • You can store your template arguments in class data member of std::tuple type and the use std::apply in order to apply stored arguments to provided function.

    So, let's say you have an Action class like this:

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

    where you set arguments through constructor Action action(1, 2, 3); or through separate function action.set(3, 2, 1);.

    Then your main function can look like this:

    int main() {
        Action action(1, 2);
    
        action.apply([](int a, int b) {
            std::cout << "a + b = " << (a + b) << std::endl;
        });
    
        return 0;
    }
    

    Check live example