Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a templated function as argument to another function

Problem

I am trying to make a function which searches for a type in a parameter pack, then creates a lambda which invokes another function with that type as a template parameter e.g.:

auto fn = findType<MyType, SomeType, OtherType>("OtherType");
fn(otherFn) == otherFn<OtherType>();

I would like to write something like this:

template<class T, class ...Ts>
auto findType(const std::string& name) {
    if (refl::is_reflectable<T>() && refl::reflect<T>().name == name) {
        return []<class Fn>(Fn fn) {
            fn<T>();
        };
    }
    return findType<Ts...>(name);
}

However, C++ doesn't seem to recognise that fn could be parameterised with template types.

I am using gcc10 and C++20, so if possible, I can also use concepts.

I believe the problem can be summed up as: How can I pass a template-parameterised function into another function?

template<class C>
void fn() {}

template<class Fn, class Arg>
void mainFn(Fn fn) {
    fn<Arg>(); // ???
}

Attempted searches

I had looked at template template parameters, but that seems to be only for templating types, not function calls.

I had also looked at C++ concepts, but std::invokable doesn't take in template parameters and requirements also don't seem to allow for such expressions:

return []<class Fn>(Fn fn) requires requires { fn<T>(); } {
like image 829
Moon Cheesez Avatar asked Oct 28 '25 08:10

Moon Cheesez


1 Answers

Function parameters are variables. Not variable templates; just regular old variables. And a non-template variable cannot be given template parameters.

You cannot pass a function template anywhere. You can only pass a particular instantiation of a function template. The closest you can get to what you want is to pass a type that has a templated operator() overload, but unless you can provide the template parameters through deduction, the only way to invoke it is via fn.operator()<TemplateArguments>(params). So you may as well have given it a meaningful name.

like image 187
Nicol Bolas Avatar answered Oct 29 '25 22:10

Nicol Bolas