函数模板特化的别名
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
}
我想像这样为 foo 的特化创建别名:
constexpr auto foo1 = &foo<f1>;
constexpr auto foo2 = &foo<f2>;
并像这样调用函数:foo1(1,2);foo2(1,2);
有什么办法可以在 C++ 中实现这一点?谢谢!
编辑:
foo() 不是 f1 的包装器,它是调用 f1 或 f2 的函数。我需要在通话前后做一些额外的事情。 F 是一个仿函数,我想要一个 'short cut' 到 foo 的特化。 上面的代码是一种伪代码。
评论中有一些好的方法: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
我们在这里做的技巧是我们让模板参数成为对函数的引用,这很老套但据我所知是合法的。
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
设置要使用的不同默认大小写函数。
#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
) 将帮助函数存储为值,以防由于某种原因,这些函数可能会在调用者对象之前超出范围 ( 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);
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 的特化创建别名:
constexpr auto foo1 = &foo<f1>;
constexpr auto foo2 = &foo<f2>;
并像这样调用函数:foo1(1,2);foo2(1,2);
有什么办法可以在 C++ 中实现这一点?谢谢!
编辑: foo() 不是 f1 的包装器,它是调用 f1 或 f2 的函数。我需要在通话前后做一些额外的事情。 F 是一个仿函数,我想要一个 'short cut' 到 foo 的特化。 上面的代码是一种伪代码。
评论中有一些好的方法: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
我们在这里做的技巧是我们让模板参数成为对函数的引用,这很老套但据我所知是合法的。
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
设置要使用的不同默认大小写函数。
#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
) 将帮助函数存储为值,以防由于某种原因,这些函数可能会在调用者对象之前超出范围 ( 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);