网络上有很多使用 STL 传递函数或函数对象作为参数的示例,例如 std::count 。
如何编写自己的接受此类参数的函数?
举一个简单的例子,假设我的类(class)是:
struct Foo{
int val=0;
int methodinc()const{return val+1};
}
我想定义一个函数 funcall,例如:
int funcall (foo arg, function f)
{return f(arg); }
其中声明“function”是我不确定的。术语“funcall”来自 Lisp,其中 (funcall f a b c)
只是将 f
应用于参数 a b c。
那么这样的事情应该有效:
Foo ff;
funcall(ff,Foo::methodinc); // should return 1
funcall(ff, [](Foo x) {return x.val+1;}) // should return 1
有哪些简单的方法可以实现这一目标?
我将这些编写为调试助手,“funcall”将用作我自己的实现的一部分,就像我自己的数据结构的 count、remove-if、transform 和其他类似采用函数参数的 STL 函数的类似物。但我不想编写复杂的模板表达式来定义我的代码。
这个问题的最初答案表明声明和使用函数参数的整个概念有点模糊,至少对我来说是这样。也许在解决 funcall 之前,一个更简单的任务可能只是将函数参数传递给另一个函数,而不是使用它。例如,在 C++ 中,要计算 vector v,我必须编写
std::count(v.begin, v.end(), [](int j){return j>3})
如何编写一个始终对整个 vector 进行计数的计数,以便:
mycount(v,[](int j){return j>3})
和上面一样吗?这个“mycount”可以用于成员函数指针而不是 lambda 吗?
这个问题与“funcall”问题基本相同,但不需要实际调用传递的函数对象。
最佳答案
通常,函数模板最适合这种灵活性需求:
template <typename F, typename T>
auto funcall(T && t, F f) -> decltype(f(std::forward<T>(t))
{
return f(std::forward<T>(t));
}
而不是尾随返回类型和 decltype
您还可以使用result_of
特质:
template <typename F, typename T>
typename std::result_of<F(T&&)>::type funcall(T && t, F f)
{
return f(std::forward<T>(t));
}
或者,在 C++14 中,您可以直接说 decltype(auto) funcall(T && t, F f)
没有尾随返回类型,它将自动推导。
制作F
的主要原因推导的模板参数而不是固定类型(例如 std::function<R(T)>
是允许您直接使用 lambda 和 funcall
/bind
表达式调用 mem_fn
,这些表达式具有不可知的类型。直接传递这些允许有效的内联机会,而相比之下,创建 std::function
对象的成本相当昂贵。
关于c++ - C++ 中的 funcall : declaring functions that take functions as parameters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23711999/