Applying an operation on each element in a tuple

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.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s