0

I needed to expand a tuple so that I can apply it's argument to a function. It was surprisingly easy to write.

template<template<class...> class Tup, class... Ts, class F>
decltype(auto) apply(F f, Tup<Ts...> &tup){
   return f(std::forward<Ts>(std::get<Ts>(tup))...);
}

And it can be used like this

auto it = std::make_tuple(1,2);
cout << apply([](int a, int b){return a + b;},it) << endl;

But what if I actually want to move the elements of the tuple into the function?

So I tried something more general

template<template<class...> class Tup, class... Ts, class F>
decltype(auto) apply(F f, Tup<Ts...> &&tup){
   return f(std::forward<Ts>(std::get<Ts>(tup))...);
}

but then it only works with rvalues

auto it = std::make_tuple(1,2);
cout << apply([](int a, int b){return a + b;},std::move(it)) << endl;

For lvalue references I get

error: no matching function for call to 'apply'
    cout << apply([](int a, int b){return a + b;},it) << endl;
            ^~~~~

What am I doing wrong?

Edit: It might not be the best example because I am using ints which will always be copied.

Maik Klein
  • 15,548
  • 27
  • 101
  • 197
  • The original code you posted doesn't work. `std::get` only works if each type in `Ts` is unique. – Cornstalks Nov 22 '15 at 00:55
  • 1
    Most of the answers in the duplicate are obsolete. The most modern one I could find is [this one](http://stackoverflow.com/a/19060157/701092). – David G Nov 22 '15 at 01:09
  • @0x499602D2 Haha, my current version looks almost the same. He just forwards the tuple into std::get where I forward outside of the std::get, not sure which one is right. I probably start another question. – Maik Klein Nov 22 '15 at 01:18
  • You don't need to forward the result of `std::get`. That is done automatically. As for forwarding the tuple itself within expression the pack expansion appears, I believe that would be incorrect if `tup` referred to an rvalue as it would be moved more than once. So `get(tup)` is the correct form. – David G Nov 22 '15 at 01:46
  • @MaikKlein : He also takes the tuple as a forwarding reference where you don't. I.e., his use of `forward` is correct, yours is not. ;-] – ildjarn Jan 02 '16 at 05:09

0 Answers0