How to write a function template which calls a function, but with the parameters passed in rotated manner: the last parameter should become as the first one for the called function?
This does the job, but PARAMETERS cannot be deduced:
template <typename ...PARAMETERS, typename LAST, typename FN>
void call_rotated(FN fn, PARAMETERS &&...parameters, LAST &&last) {
fn(std::forward<LAST>(last), std::forward<PARAMETERS>(parameters)...);
}
In the next example, calling call_rotated(print, 1, 2, "was_last") calls the print function with parameters ("was_last", 1, 2), so it prints "was_last 1 2":
#include <utility>
#include <cstdio>
template <typename ...PARAMETERS, typename LAST, typename FN>
void call_rotated(FN fn, PARAMETERS &&...parameters, LAST &&last) {
fn(std::forward<LAST>(last), std::forward<PARAMETERS>(parameters)...);
}
void print(const char *l, int a, int b) {
printf("%s %d %d\n", l, a, b);
}
int main() {
call_rotated<int, int>(&print, 1, 2, "was_last");
}
But the problem is that I had to specify the template parameters <int, int> to call_rotated. Is it possible to write call_rotated in a way that deduction works for it?
With std::index_sequence, you might do:
template <typename FN, typename ...Ts>
void call_rotated(FN fn, Ts&&...parameters)
{
return [&]<std::size_t... Is>(std::index_sequence<Is...>){
return fn(std::get<(sizeof...(Is) - 1 + Is) % sizeof...(Is)>(
std::forward_as_tuple(std::forward<Ts>(parameters)...))...);
}(std::index_sequence_for<Ts...>());
}
Above code need C++20, but might be adapted for older standard.
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With