我想知道是否有一个轻量级版本的std :: function只适用于函数指针,但没有像常规函数指针那样可怕的语法。
Aka是这样的:
int square(int x)
{
return x*x;
}
//...
function_ptr<int (int)> = square;
Ofc bind和所有其他花哨的东西std :: function支持都会失败,但我很好,如果我需要std :: function我会用它。
答案 0 :(得分:2)
根据您要使用此内容的上下文,它可以像auto
和/或decltype
一样简单:
#include <iostream>
int main()
{
auto f = square;
std::cout << f(5) << std::endl;
// define a type
using F = decltype(&square);
F g = square;
std::cout << g(5) << std::endl;
}
答案 1 :(得分:2)
您要求的是模板从签名转换为指向函数的签名,即添加指向该类型的指针。这已经在标准库中完成了:
std::add_pointer<X>::type
但是,由于你想要的是 nicer 语法,你可以添加模板别名:
template <typename T>
using ptr = typename std::add_pointer<T>::type;
然后您可以直接在容器中使用它:
void f(int);
std::vector<ptr<void (int)>> v; // vector of pointers to functions taking `int`
v.push_back(&f);
答案 2 :(得分:1)
如果您不想直接使用typedef
,可以编写 opaque 包装器。使用可变参数模板的原型实现如下。相同的技术可以扩展到其他可调用的对象,如lambdas。
#include <iostream>
template<typename T>
struct function_ptr {};
template<class R, class... Args>
struct function_ptr<R(Args...)>{
typedef R (*funcType)(Args...);
function_ptr(funcType f) : _f(f) {}
funcType _f;
R operator()(Args... args) { return _f(args...);}
};
int square(int x) {
return x*x;
}
int main() {
function_ptr<int (int)> f = square;
std::cout << f(2) << std::endl;
}