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的专业化“捷径”。 上面的代码是一种伪代码。
答案 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。
答案 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