I am trying to write a wrapper function that executes a given function every N times (something similar to Google logging's LOG_EVERY_N).
What I have done so far is:
#include <cstddef>
#include <functional>
#include <utility>
template<size_t N, typename Callable, typename... Args>
void call_every_n(Callable&& c, Args... args)
{
static size_t __counter = 0;
if(__counter == N - 1)
{
std::invoke(std::forward<Callable>(c), std::forward<Args>(args)...);
__counter = 0;
} else ++__counter;
}
#define CALL_EVERY_N(N, FUNC, ...) call_every_n<N, decltype(&FUNC), decltype(__VA_ARGS__)>(FUNC, __VA_ARGS__)
The problem is with the usage of the static variable for the internal counter but I cannot figure out how to achieve this differently. In fact, this code works as expected until I call the same function with the same N.
This is an example which demonstrates the issue:
#include <iostream>
void test(int a, int num)
{
std::cout << num << " = " << a << "\n";
}
int main() {
for(int i = 1; i < 20; ++i)
{
CALL_EVERY_N(3, test, i, 1);
CALL_EVERY_N(3, test, i, 2);
}
return 0;
}
This code outputs:
1 = 2
2 = 3
1 = 5
2 = 6
1 = 8
2 = 9
1 = 11
2 = 12
1 = 14
2 = 15
1 = 17
2 = 18
i.e. the exact same static variable is used (and then modified) by the two different functions.
I also would like to enforce the fact that Callable must be a function returning void, how could I do it?