将函数模板转换为模板仿函数
Convert function template into templated functor
我想知道是否可以从函数模板创建函数对象。以下 Functor
结构从函数创建函数对象:
#include <iostream>
template <typename F, F* f>
struct Functor {
template <typename... Ar>
auto operator()(Ar&&... rg) -> decltype(f(std::forward<Ar>(rg)...)) {
return f(std::forward<Ar>(rg)...);
}
};
int plus_one(int a) {
return a + 1;
}
int main () {
std::cout << Functor<decltype(plus_one), &plus_one>()(1) << "\n";
return 0;
}
这会创建一个类似于
的结构
struct PlusOne {
int operator()(int a) {
return a + 1;
}
}
现在,我想使用函数模板而不是函数:
template <typename T>
T plus_one(T a) {
return a + 1;
}
我希望能变成类似
的东西
struct PlusOne {
template <class T>
T operator()(T a) {
return a + 1;
}
};
这可能吗?我问这个的原因之一是我 read C++14 中的通用 lambda 表达式正在变成类似于我所追求的仿函数:
For example, this generic lambda-expression containing statement:
auto L = [](const auto& x, auto& y){ return x + y; };
might result in the creation of a closure type, and object that behaves similar to the struct below:
struct {
template <typename T, typename U>
auto operator()(const T& x, U& y) const { return x + y; }
} L;
所以我天真地希望可能存在一些设施来实现我所追求的目标。不过我仅限于 C++11。
不,这是不可能的。模板名称本身的使用方式非常有限。在传递它之前,您必须将它包装在 class 中。在 C++14 中,使用 lambda 来包装对函数的调用似乎是最简单的方法。然后你可以在很多方面使用它:
auto wrapper = [](const auto& x){ return plus_one(x); }
std::cout << wrapper(42) << "\n";
std::cout << std::invoke(wrapper, 42) << "\n";
std::cout << std::bind(wrapper, 42)() << "\n";
// etc.
在 C++11 中,我们有点搞砸了。我们必须自己编写包装器:
struct Wrapper {
template <typename T>
auto operator()(const T& x) const
{
return plus_one(x);
}
};
然后
Wrapper wrapper;
// same usage
我想知道是否可以从函数模板创建函数对象。以下 Functor
结构从函数创建函数对象:
#include <iostream>
template <typename F, F* f>
struct Functor {
template <typename... Ar>
auto operator()(Ar&&... rg) -> decltype(f(std::forward<Ar>(rg)...)) {
return f(std::forward<Ar>(rg)...);
}
};
int plus_one(int a) {
return a + 1;
}
int main () {
std::cout << Functor<decltype(plus_one), &plus_one>()(1) << "\n";
return 0;
}
这会创建一个类似于
的结构struct PlusOne {
int operator()(int a) {
return a + 1;
}
}
现在,我想使用函数模板而不是函数:
template <typename T>
T plus_one(T a) {
return a + 1;
}
我希望能变成类似
的东西struct PlusOne {
template <class T>
T operator()(T a) {
return a + 1;
}
};
这可能吗?我问这个的原因之一是我 read C++14 中的通用 lambda 表达式正在变成类似于我所追求的仿函数:
For example, this generic lambda-expression containing statement:
auto L = [](const auto& x, auto& y){ return x + y; };
might result in the creation of a closure type, and object that behaves similar to the struct below:
struct { template <typename T, typename U> auto operator()(const T& x, U& y) const { return x + y; } } L;
所以我天真地希望可能存在一些设施来实现我所追求的目标。不过我仅限于 C++11。
不,这是不可能的。模板名称本身的使用方式非常有限。在传递它之前,您必须将它包装在 class 中。在 C++14 中,使用 lambda 来包装对函数的调用似乎是最简单的方法。然后你可以在很多方面使用它:
auto wrapper = [](const auto& x){ return plus_one(x); }
std::cout << wrapper(42) << "\n";
std::cout << std::invoke(wrapper, 42) << "\n";
std::cout << std::bind(wrapper, 42)() << "\n";
// etc.
在 C++11 中,我们有点搞砸了。我们必须自己编写包装器:
struct Wrapper {
template <typename T>
auto operator()(const T& x) const
{
return plus_one(x);
}
};
然后
Wrapper wrapper;
// same usage