8

Is there anything better in c++17 (maybe C++2a) than the classic C++14 way to unpack variadic tuple with std::index_sequence?

Anything better than this:

template <typename ...I>
class MultiIterator
{
public:
    MultiIterator(I const& ...i)
        : i(i...)
    {}

    MultiIterator& operator ++()
    {
        increment(std::index_sequence_for<I...>{});
        return *this;
    }


private:
    template <std::size_t ...C>
    void increment(std::index_sequence<C...>)
    {
        std::ignore = std::make_tuple(++std::get<C>(i)...);
    }

    std::tuple<I...> i;
};

Like fold expression, structured-bindings? Any hint? I can accept answer why I cannot use these mentioned C++17 features here - but I prefer "solution.

PiotrNycz
  • 23,099
  • 7
  • 66
  • 112

1 Answers1

15

Since C++14 we have generic lambdas, and since C++17 we have fold expressions and std::apply effectively hiding the usual unpack logic:

std::apply( [](auto&... i){ ((void)++i,...); }, some_tuple );

note: for your information, the (void) thing is just to avoid any custom comma operator to kick in... you never know :)

Massimiliano Janes
  • 5,524
  • 1
  • 10
  • 22
  • 2
    nice, but still a hack. Upvoted because it it's not your fault the C++ doesn't allow a straight syntax. – bolov Jan 26 '18 at 15:56
  • 1
    @bolov yep, the most hackish thing is the need to use the comma operator; I wonder why we cannot just `expr;...;` ... but I guess this would be problematical grammar-wise – Massimiliano Janes Jan 26 '18 at 16:00
  • Can apply you solution to my example with increment? I mean some example of usage – PiotrNycz Jan 26 '18 at 16:05
  • @PiotrNycz yes, just replace the `increment()` call with the above, with `some_tuple` replaced with the `i` member – Massimiliano Janes Jan 26 '18 at 16:07