# How to "duplicate" template parameter pack expansion?

Vahagn

Consider this code:

``````template < size_t... Indices >
void something(std::index_sequence<Indices...>)
{
// how to obtain the following call where N is sizeof...(Indices)?
// foo(f(0),g(0),f(1),g(1),...,f(N-1),g(N-1));
}
``````
Barry

The key to answering a question like:

``````// how to obtain the following call where N is sizeof...(Indices)?
// foo(f(0),g(0),f(1),g(1),...,f(N-1),g(N-1));
``````

is to formulate how to actually generate such a pack expansion. We have `2N` arguments, which would like:

``````+=====+======+
| idx | expr |
+-----+------+
|  0  | f(0) |
|  1  | g(0) |
|  2  | f(1) |
|  3  | g(1) |
|   ....
+=====+======+
``````

In C++17, we can write such an expression with `if constexpr`:

``````template <size_t I>
auto expr() {
if constexpr (I % 2 == 0) {
// even indices are fs
return f(I / 2);
} else {
// odds are gs
return g(I / 2);
}
}
``````

Which can even be a lambda that takes an `integral_constant` as an argument. So we really just need to turn our `N` arguments into `2N` arguments, which is just a matter of adding more indices:

``````template <auto V>
using constant = std::integral_constant<decltype(V), V>;

template < size_t... Indices >
void something(std::index_sequence<Indices...>) {
auto expr = [](auto I) {
if constexpr (I % 2 == 0) {
return f(I / 2);
} else {
return g(I / 2);
}
}

return foo(
expr(constant<Indices>{})...,                     // 0, ..., N-1
expr(constant<Indices + sizeof...(Indices)>{})... // N, ..., 2N-1
);
}
``````

Collected from the Internet

edited at