Currently, I have a code like
#include <cstdint>
#include <iostream>
template<std::uint32_t idx>
void f() {
std::cout << "f(" << idx << ")\n";
}
template<std::uint32_t n>
void loop1() {
f<n>();
if constexpr (n > 0) {
loop1<n - 1>();
}
}
template<std::uint32_t idx>
void g() {
std::cout << "g(" << idx << ")\n";
}
template<std::uint32_t n>
void loop2() {
g<n>();
if constexpr (n > 0) {
loop2<n - 1>();
}
}
int main() {
loop1<4>();
loop2<2>();
}
It’s necessary for f
, g
, loop1
and loop2
to be function templates. Now, I have to add more functions, but loop1
and loop2
will always be the same, a recursive template loop.
How can I pass the function template as (template) argument to loop
to achieve something like:
#include <cstdint>
#include <iostream>
template<std::uint32_t idx>
void f() {
std::cout << "f(" << idx << ")\n";
}
template<std::uint32_t idx>
void g() {
std::cout << "g(" << idx << ")\n";
}
template<std::uint32_t n, typename h>
void loop() {
h<n>();
if constexpr (n > 0) {
loop<n - 1, h>();
}
}
int main() {
loop<4, h>();
loop<2, h>();
}
I prefer to pass the function as template argument at compile time, but a solution to pass the function template as function argument at runtime would also solve my problem, e.g.
#include <cstdint>
#include <iostream>
template<std::uint32_t idx>
void f() {
std::cout << "f(" << idx << ")\n";
}
template<std::uint32_t idx>
void g() {
std::cout << "g(" << idx << ")\n";
}
template<std::uint32_t n, typename T>
void loop(T h) {
h<n>();
if constexpr (n > 0) {
loop<n - 1>(h);
}
}
int main() {
loop<4>(h);
loop<2>(h);
}
or
#include <cstdint>
#include <iostream>
template<std::uint32_t idx>
void f() {
std::cout << "f(" << idx << ")\n";
}
template<std::uint32_t idx>
void g() {
std::cout << "g(" << idx << ")\n";
}
template<std::uint32_t n, template<std::uint32_t> typename F>
void loop(F h) {
h<n>();
if constexpr (n > 0) {
loop<n - 1>(h);
}
}
int main() {
loop<4>(h);
loop<2>(h);
}
Is this even possible? I know, that all of my approaches are wrong syntax. It’s just to illustrate, what I want to achieve.
>Solution :
You cannot do this with free functions but you can do something similar to what you want to have with class template static member functions:
#include <cstdint>
#include <iostream>
template<std::uint32_t idx>
struct F {
static void function() {
std::cout << "f(" << idx << ")\n";
}
};
template<std::uint32_t idx>
struct G {
static void function() {
std::cout << "g(" << idx << ")\n";
}
};
template<std::uint32_t n, template<std::uint32_t> typename T>
void loop() {
T<n>::function();
if constexpr (n > 0) {
loop<n - 1, T>();
}
}
int main() {
loop<4, F>();
loop<2, G>();
}
Here’s a demo.