Reputation: 7673
The question is simple (but not so the solution I guess...).
I want to apply a function to index 0 of n tuples with args, later to index 1 of tuple the same tuples with args... and so on.
Given this:
template <auto Func, class... Tuples, class... Fargs, std::size_t... Is>
auto applyInLockStep(std::index_sequence<Is...>,
Tuples &&... tups,
Fargs &&...args) {
return (Func(std::get<Is>(tups), std::forward<Fargs>(args)...), ...);
}
And assuming this is the call:
using Tup = std::tuple<float, float, float>;
Tup t1, t2;
constexpr auto f = [&]<class T1E, class T2E>(T1E && t1E,
T2E && t2E,
float t) {
return myf(std::forward<T1E>(t1E), std::forward<T2E>(t2E), t);
};
applyInLockStep<f>(make_index_sequence<tuple_size_v<Tup1>>{}, t1, t2, 1.0f);
I want this expansion:
Func(std::get<0>(tup0), std::get<0>(tup1), 1.0f),
Func(std::get<1>(tup0), std::get<1>(tup1), 1.0f),
...
The problem is in this expression, in std::get<Is>(tups)
concretely:
Func(std::get<Is>(tups), std::forward<Fargs>(args)...), ...)
I want to expand tups for the same index, but not Is, but if I do this it will only expand tups inside std::get<0>(tup1, tup2), which I do not want:
Func(std::get<Is>(tups...), std::forward<Fargs>(args)...), ...)
And if I do this:
Func(std::get<Is>(tups)..., std::forward<Fargs>(args)...), ...)
it will expand tups and Is..., but I do not want Is to be expanded.
Not sure if it is doable or not and how.
Upvotes: 1
Views: 75
Reputation: 217448
At first, in
// ..
auto applyInLockStep(std::index_sequence<Is...>,
Tuples &&... tups,
Fargs &&...args)
FArgs
is non-deducible, Tuples
would deduce all, so FArgs
would be an empty pack.
I will bypass by grouping tups
inside another std::tuple
// ..
auto applyInLockStep(std::index_sequence<Is...>,
std::tuple<Tuples...> tups,
Fargs &&...args)
then, you might create sub-function to allow variadic expansion in the direction you want:
template <auto Func,
class... Tuples,
class... Fargs,
std::size_t I>
auto applyInLockStep(std::integral_constant<std::size_t, I>,
std::tuple<Tuples...> tups,
Fargs &&...args)
{
return std::apply([&](auto&&... tup) {
return Func(std::get<I>(tup)..., std::forward<Fargs>(args)...);
}, tups);
}
template <auto Func,
class... Tuples,
class... Fargs,
std::size_t... Is>
auto applyInLockStep(std::index_sequence<Is...>,
std::tuple<Tuples...> tups,
Fargs &&...args)
{
return (applyInLockStep<Func>(std::integral_constant<std::size_t, Is>{},
std::forward<std::tuple<Tuples...>>(tups),
std::forward<Fargs>(args)...),
...);
}
Upvotes: 2