Home > Mobile >  Invoking a tuple containing both the invocable and the arguments
Invoking a tuple containing both the invocable and the arguments

Time:02-01

I am trying to invoke the first parameter in a tuple with the second one as a parameter, but can't figure out how to do it.

Example:

#include <tuple>
#include <functional>

struct S {
    void operator()(int) {}
};

int main() {
    S s;
    auto t = std::make_tuple(s, 3);
    std::invoke(s, 3);
    // std::apply(std::invoke, t); // This is what I want to do
    // std::apply(std::invoke<S, int>, t); // I would settle for this "Good Enough"
}

but the code above doesn't compile, and the error is very unhelpful (to me):

error: no matching function for call to '__invoke(void (&)(S&&, int&&), std::__tuple_element_t<0, std::tuple<S, int> >&, std::__tuple_element_t<1, std::tuple<S, int> >&)'

(this is from the "good enough" attempt)

Anyone know how to do this, or if it can't be done?

CodePudding user response:

Wrapping overload/template function in lambda solves lot of issues:

std::apply([](auto&&... args){ std::invoke(args...); }, t);

Possibly with forwarding:

std::invoke(std::forward<decltype(args)>(args)...);

Else as std::invoke is a template function (taking forwarding reference), you need to correct type:

std::apply(std::invoke<S&, int&>, t);
std::apply(std::invoke<S, int>, std::move(t));

Demo

About the error reading: std::__tuple_element_t<0, std::tuple<S, int> >& is S&, so error simplify to

error: no matching function for call to __invoke(void (&)(S&&, int&&), S&, int&)"

You would need void (&)(S&, int&) (or pass S&&, int&& as argument of the function)

CodePudding user response:

std::apply is an option, but you need to use a lambda to invoke f appropriately:

std::apply([](auto f, auto... args) { 
      std::invoke(f, args...);
    }, t);

The reason why std::apply(std::invoke<S, int>, t) doesn't work is that std::invoke is instantiated as std::invoke(S&&, int&&). Since t is an lvalue, it cannot bind to an rvalue reference.

  •  Tags:  
  • Related