3

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 ?

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

Comments

1

You can make use of 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();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.