Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I pass a function template as (template) argument to a function template?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading