james james - 2 months ago 13
C++ Question

Alias to a function template specialization

int f1(int a, int b) { return a+b; }
int f2(int a, int b) { return a*b; }

template <typename F> void foo(int i, int j)
{
// do some processing before
F(i,j);
// do some processing after
}


I want to make an alias to a specialization of foo like this:

constexpr auto foo1 = &foo<f1>;
constexpr auto foo2 = &foo<f2>;


and call the function like this:
foo1(1,2);foo2(1,2);

Any way to achieve this in C++? Thanks!




Edit:
foo() is not a wrapper of f1, it is a function that calls f1 or f2. I need to do something extra before and after the call. F is a functor and I want a 'short cut' to the specialization of foo. The code above is kind of psuedo code.

Answer

There are some good approaches in the comments: std::bind, using a lambda, passing an instance of F into the function, so I'll provide an alternative.

If the function type that you will pass into foo will always be int(int, int), then you make the template parameter be a non-type template parameter, and then instantiate it with one of your functions:

int f1(int a, int b) { std::cout<<"f1\n"; return a+b; }
int f2(int a, int b) { std::cout<<"f2\n"; return a*b; }

template <int(*F)(int, int)> 
void foo(int i, int j)
{
    F(i,j);   
}

And then call it like so:

int main()
{
    constexpr auto foo1 = foo<f1>;
    constexpr auto foo2 = foo<f2>;
    foo1(1,2);
    foo2(1,2);
}

Output:

f1
f2

The trick we're doing here is that we're making the template parameter be a reference to a function, which is hacky but legal AFAIK.

Demo