别名到函数模板特化

时间:2016-09-19 15:51:11

标签: c++ templates alias

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 
}

我想像foo那样为foo的特化做一个别名:

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

并调用此函数:foo1(1,2);foo2(1,2); 有什么办法在C ++中实现这一点?谢谢!

修改 foo()不是f1的包装器,它是一个调用f1或f2的函数。我需要在通话前后做一些额外的事情。 F是一个仿函数,我想要foo的专业化“捷径”。 上面的代码是一种伪代码。

2 个答案:

答案 0 :(得分:4)

评论中有一些好的方法:std :: bind,使用lambda,将F的实例传递给函数,所以我将提供另一种选择。

如果要传递到foo的函数类型始终为int(int, int),则将模板参数设置为非类型模板参数,然后使用以下某个函数对其进行实例化:

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);   
}

然后这样称呼它:

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

输出:

  

f1
  F2

我们在这里做的诀窍是我们将模板参数作为对函数的引用,这是一个hacky但合法的AFAIK。

Demo

答案 1 :(得分:1)

accepted answer是OP请求的现场点。为了补充这个答案:另一种方法可能是让int(int, int)函数指针成为函数的附加参数(在这种情况下我们不需要使用模板技术),并使用std::bind来设置了解要使用的不同默认案例函数。

#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;
}

上述变体可以允许使用函数包装器(std::function)将帮助函数存储为值,以防由于某种原因,这些函数会在调用者对象之前超出范围({{ 1}},foo1,...)。

foo2