I ran into this when implementing the C++14 version of zip for cppitertools.
Given a tuple of iterators, increment each of those iterators using ++. Assuming I already have a std::index_sequence
with the indices as Is...
, I initially had something like this:
void increment_all() { ++std::get<Is>(this->tup)...; }
However, this doesn’t work because the expansion cannot appear outside of a function call or initializer list. This can be worked around with a function that absorbs everything. My original implementation was to make it variadic like so:
template <typename... Ts> void absorb(Ts&&...) { }
this isn’t really necessary though, since we have the older … that works just as well. The below meets the requirements:
//void absorb(...) {} //UPDATE DON'T USE THIS READ BELOW void increment_all() { absorb(++std::get<Is>(this->tup)...); }
And this works for my purposes. Note that this is a function call, so the order in which the iterators will be incremented is unspecified. If it’s important to you for it to happen in a 0, 1, …, N order, then you can use an initializer list if all of the operations will return the same type, or use other solutions if they don’t.
UPDATE: I reverted to using the templated absorb
because the version with just … will attempt to make copies of its input arguments. This is not what I ever want to happen. Even though the copies would be optimized out, it still prevents the function from working with non-copyable (in some cases, only non-movable) types.