Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapper function which calls another function with the arguments passed in a rotated order

Tags:

c++

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?

like image 565
geza Avatar asked Jun 12 '26 09:06

geza


1 Answers

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

like image 57
Jarod42 Avatar answered Jun 14 '26 01:06

Jarod42



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!