回答如下问题的关键:
// 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));
是制定如何实际生成这样的包扩展。我们有 2N 参数,它们想:
+=====+======+
| idx | expr |
+-----+------+
| 0 | f(0) |
| 1 | g(0) |
| 2 | f(1) |
| 3 | g(1) |
| ....
+=====+======+
在 C++17 中,我们可以用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);
}
}
它甚至可以是一个以 integral_constant 为参数的 lambda。所以我们真的只需要将我们的N 参数变成2N 参数,这只是添加更多索引的问题:
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
);
}