Home > OS >  Is it possible to pass static function as template argument without adding new function argument?
Is it possible to pass static function as template argument without adding new function argument?

Time:02-17

One can pass callback to other function using template to abstract from real callback type:

float foo(int x, int y)  {return x*y;}

template<class F>
void call_it(F f, int a, int b)
{
    f(a,b);
}

There is a cost of passing f as an argument and calling it indirectly. I wonder if, in case f is a static function it is possible to pass it somehow to template function "directly", without adding a callable to the function argument list, so that the call could be bound statically. I see the analogy to passing an integer value as template argument. It doesn't require adding any new function arguments because it passes the integer just as immediate value into the function code:

template<int X> int foo(int y) {return X y;}

Here is a non-working code presenting what I'd like to achieve:

template<class F>
void call_it(int a, int b)
{
    F(a,b);    // Assume that F is a static function and can be called directly
}

Is there any way to achieve it?

CodePudding user response:

You can use a non-type template parameter. To still allow all kinds of callables you can use auto:

#include <iostream>

struct foo {
    static float bar(int a,int b){
        std::cout << "foo: " << a << " " << b;
        return a   b;
    }
};

template <auto f>
float call_it(int a,int b){
    return f(a,b);
}

int main() {
    call_it<&foo::bar>(1,2);
}

or without auto:

template <float (*f)(int,int)>
float call_it(int a,int b){
    return f(a,b);
}

CodePudding user response:

Quite simple:

float foo(int x, int y)  {return x*y;}

template<auto f>
auto call_it(int a, int b)
{
    return f(a,b);
}

int main()
{
    std::cout << "ret val: " << call_it<foo>(1,2) << std::endl;
}

It is easy as you can use a non type template parameter. You can specify it fully with the type or more easy by using auto. The last has the problem that you can pass everything and the failure will be reported late when you call the non type template parameter. Maybe using a concept which checks for call ability is the best approach.

  •  Tags:  
  • c
  • Related