What is the best way to save function arguments and call the function later?

user1806566

In C++14, I would like to be able to save function arguments and call the function at a later time. My goal is to be able to do something like:

auto delayed_function{ some_callable };

delayed_function( 1, 2, 3 );   // arguments are stored, but some_callable is not called yet
delayed_function.call();  // some_callable called with (1,2,3)

The main issue is that I need to take the arguments and store them. It seems to be that storing them in a std::tuple would work the best. The question is what exactly the type of the tuple should be. My thinking is that I need to deduce the type of the tuple when the arguments are provided (rather than trying to deduce the type from the arguments to the callable), since when the arguments are provided, they may be references, rvalues, etc., and I'll only know that from the argument types. What that means, however, is that even if I know the type of the callable, I won't know the type of the tuple except in the template method where the arguments are provided (operator() in my above example). So it sounds like I need some sort of type erasure. My implementation for the argument storage is currently:

template <typename Callable>
class arg_tuple
{
public:
  template <typename ... Args>
  arg_tuple( Args&&... args )
  {
    using TupleType = decltype( std::make_tuple(std::forward<Args>(args)...) );
    args_ =
      std::make_unique< typed_arg<TupleType> >(
        std::make_tuple(std::forward<Args>(args)...)
        );
  }

  void
  invoke( Callable f )
  {
    args_->invoke( f );
  }
private:

  template <typename T = void>
  struct untyped_arg {
    virtual ~untyped_arg() = default;

    virtual void invoke( Callable f ) = 0;
  };


  template <typename T>
  struct typed_arg
    : public untyped_arg<> {
    template <typename Arg>
    typed_arg( Arg&& arg )
      : value(std::forward<Arg>(arg) ) {}

    virtual void
    invoke( Callable f )
    {
      // By moving value, I can only call invoke once, but it potentially saves
      // copying, and I can use move-only types in the arg list.
      my_apply( f, std::move(value) );
    }

    T  value;
  };

  std::unique_ptr<untyped_arg<>>  args_;
};

where "my_apply" is essentially std::apply, but since I'm using C++14, I had to implement it manually. The good news is that this basically works:

  auto  f = [](int i) { printf("i+3=%d\n", i+3); };
  using Callable = decltype(f);
  arg_tuple<Callable>  t(20);
  t.invoke(f);

What bothers me about the implementation, however, is that Callable is a template parameter to arg_tuple. I would really like it to be a template parameter to the invoke method, not the entire class. The reason I did it this way is that arg_tuple doesn't know the type of the stored tuple, so invoke needs a virtual function to be able to get down to where the type tuple type is known (typed_arg). Virtual methods cannot have template parameters, however, so that's where I get stuck.

If there's a way that I could make Callable a template method of invoke, then could make it a forwarding reference, so I wouldn't have to take it by value. Otherwise, I think I may need multiple overloads of invoke for lvalue, const lvalue, and rvalue references, in case Callable is a mutable object.

Is there a better way to do this?

Marek R

There are couple ways to do it.

Using future:

auto value = std::async(std::launch::deferred, delayed_function, 1, 2, 3);
...
value.get();

Or just using lambda:

auto f = [arg]() { return delayed_function(arg, 2, 3); }
...
f();

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

Best way to check function arguments?

From Dev

What's an efficient way to call a function with variable arguments?

From Dev

What is the best way to call a function with the result of a filter operation on a Java stream

From Dev

Best way to call a function in javascript

From Dev

Is there a way to save the function call with parameters?

From Dev

Is there a way to save the function call with parameters?

From Dev

What is the best way to invoke a function?

From Dev

What is the best way to create a function with a single argument from a function with multiple arguments?

From Dev

best way to check arguments of a function in haskell

From Dev

Best way to call an async function within map?

From Dev

what is the best way of filling map of struct in a function

From Dev

what is the best way of filling map of struct in a function

From Dev

Best pythonic way of mapping a specific function with multiple arguments

From Dev

call function by name with arguments

From Dev

What is the best way to save JNIEnv*

From Dev

Is there idiomatic pointfree way to call a function with arguments through another functions

From Dev

Best way to call Clojure function with named/default args from Java

From Dev

Best (pythonic) way to interrupt and cancel a function call in progress?

From Dev

Best way to call a jQuery function from keyup on multiple fields?

From Dev

Best way to call function on every object in array? Without for loop?

From Dev

Best way to call a function in a class from an object in that class

From Dev

How to save a function in bash for later use?

From Dev

What is happening when I call unpack() as lua's function arguments?

From Dev

Typescript & Jquery: what is the best practice to call a class into Jquery onclick function?

From Dev

What's the clearest way to indicate a function uses the 'arguments' object?

From Dev

What's the idiomatic way of calling a function with many arguments?

From Dev

What's the idiomatic way of calling a function with many arguments?

From Dev

What's the clearest way to indicate a function uses the 'arguments' object?

From Dev

What's the best way to make a parameter of a function mandatory?

Related Related

  1. 1

    Best way to check function arguments?

  2. 2

    What's an efficient way to call a function with variable arguments?

  3. 3

    What is the best way to call a function with the result of a filter operation on a Java stream

  4. 4

    Best way to call a function in javascript

  5. 5

    Is there a way to save the function call with parameters?

  6. 6

    Is there a way to save the function call with parameters?

  7. 7

    What is the best way to invoke a function?

  8. 8

    What is the best way to create a function with a single argument from a function with multiple arguments?

  9. 9

    best way to check arguments of a function in haskell

  10. 10

    Best way to call an async function within map?

  11. 11

    what is the best way of filling map of struct in a function

  12. 12

    what is the best way of filling map of struct in a function

  13. 13

    Best pythonic way of mapping a specific function with multiple arguments

  14. 14

    call function by name with arguments

  15. 15

    What is the best way to save JNIEnv*

  16. 16

    Is there idiomatic pointfree way to call a function with arguments through another functions

  17. 17

    Best way to call Clojure function with named/default args from Java

  18. 18

    Best (pythonic) way to interrupt and cancel a function call in progress?

  19. 19

    Best way to call a jQuery function from keyup on multiple fields?

  20. 20

    Best way to call function on every object in array? Without for loop?

  21. 21

    Best way to call a function in a class from an object in that class

  22. 22

    How to save a function in bash for later use?

  23. 23

    What is happening when I call unpack() as lua's function arguments?

  24. 24

    Typescript & Jquery: what is the best practice to call a class into Jquery onclick function?

  25. 25

    What's the clearest way to indicate a function uses the 'arguments' object?

  26. 26

    What's the idiomatic way of calling a function with many arguments?

  27. 27

    What's the idiomatic way of calling a function with many arguments?

  28. 28

    What's the clearest way to indicate a function uses the 'arguments' object?

  29. 29

    What's the best way to make a parameter of a function mandatory?

HotTag

Archive