Alias to a function template specialization

北慕城南 提交于 2019-12-01 01:06:29

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

dfri

The accepted answer is spot-on for the OP's request. To complement that answer: an alternative method could be letting the int(int, int) function pointer be an additional argument to the function (in which case we needn't use template techniques), and use std::bind to set up the different default case functions to be used.

#include <iostream>
#include <functional>

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

void foo(int i, int j, int (*f)(int, int)) {
  // do some processing before
  std::cout << f(i, j) << std::endl;
  // do some processing after
}

int main()
{
  const auto foo1 = std::bind(foo, std::placeholders::_1, std::placeholders::_2, &f1);
  const auto foo2 = std::bind(foo, std::placeholders::_1, std::placeholders::_2, &f2);

  foo1(5, 5);     // 10
  foo2(5, 5);     // 25
  foo(5, 5, &f3); // 0

  return 0;
}

A variation of the above could allow using function wrappers (std::function) to store the help functions as values, in cases these would, for some reason, risk going out of scope prior to the caller objects (foo1, foo2, ...).

void foo(int i, int j, const std::function<int(int, int)> f) { /* ... */ }

// ...

const auto foo1 = std::bind(foo, std::placeholders::_1, std::placeholders::_2, f1);
const auto foo2 = std::bind(foo, std::placeholders::_1, std::placeholders::_2, f2);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!