Much less painful than its C++11 equivalent. std::integer_sequence is responsible for most of the ease. Combined with auto functions, which deduce their own return type, that is.

call_with_tuple first determines the tuple_size of the tuple-like object passed in. std::make_index_sequence will result in an index sequence of 0, 1, ..., TUP_SIZE. The last argument of call_with_tuple_impl is used to deduce the Is... pack. finally the mf(std::get<Is>(tup)...) is the equivalent of mf(std::get<0>(tup), std::get<1>(tup), ..., std::get<TUP_SIZE-1>(tup)).

The std::decay_t is necessary because TupType is a universal reference.

I’m using these integer sequences more and more. They’re proving to be extremely useful in flattening complex recursive data structures and logic. C++14 rules