c++ - C++ 中的 funcall : declaring functions that take functions as parameters

标签 c++ c++11 lambda function-object

网络上有很多使用 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/

相关文章:

c++ - 派生 QMainWindow 并更改其布局

c++11 - 如何从Lambda函数返回nullptr?

java - Java 8 中的方法引用是否有具体类型?如果有,它是什么?

c++ - 在集合上使用 lambda 表达式和 find_if

javascript - 在 TypeScript 中使用箭头函数 : how to make them class methods?

c++ - Klocwork 9.6 仅在指定文件中忽略特定检查器

c++ - 未定义的“函数引用”

c++ - QMutex:销毁锁定的互斥体

c++ - 实现 std::hash<T> 时修改内部结构

c++ - operator==() 使用模板模板