【问题标题】:Passing "part" of a function pointer as an argument将函数指针的“部分”作为参数传递
【发布时间】:2012-05-28 19:25:39
【问题描述】:

我确定以前有人问过这个问题,但是很难搜索... 所以,我得到的是一个接受函数指针的函数。这个函数指针有 3 个参数。所以,我想传递给另一个函数,相同的指针,但填充了 2 个参数。

所以,是这样的:

int func1 (int (*funcptr)(int, int, int)) {
  return func2(funcptr(,8,9));
}

int func2 (int (*funcptr)(int)) {
  return (*funcptr)(2);
}

编辑: 好的,所以我现在使用 lambda 得到了这个

int func2(int (*funcptr2)(int)) {
  return (*funcptr2)(2);
}
int func1(int (*funcptr1)(int, int, int)) {
  return func2(
    [funcptr1](int i)->int {
      return (*funcptr1)(i,8,9);
    }
  );
}

但它给了我

“无法将参数 1 的 func1(int (*)(int, int, int))::<lambda(int)> 转换为 int (*)(int)int func2(int (*)(int))

【问题讨论】:

  • std::bind(也在boost
  • 也可以看到“完美转发”(你可以google一下)。 C++11 标准为您的案例提供了完美的转发。

标签: c++ function pointers lambda function-pointers


【解决方案1】:

这称为 lambda,您可以使用 newer C++ versions、std::bind、boost::bind 或 boost::function 来实现。

【讨论】:

  • lambda(即内联函数定义)是​​实现此任务的一种方式。但是,此任务被特别称为函数的“部分应用程序”:en.wikipedia.org/wiki/Partial_application
  • 那么,我会做类似return func2([](int x){funcptr(x,8,9);})
  • @duskwuff:我使用的术语更普遍(包括部分应用和类似的通用函数生成机制),但我认为我的用法不正确,至少在 C++ 世界中是这样。
  • 我不知道如何使用 lambda。我已经更新了我的问题。
【解决方案2】:

要回答您更新的问题,捕获变量的 lambda(就像您的 lambda 对 funcptr1 所做的那样)不能转换为函数指针。直观地说,这是有道理的,因为您的 lambda 必须为每个 lambda 存储这个捕获的变量;而函数指针无法做到这一点。

最好的解决方案可能是采用std::function 类型的参数,它是任何可调用类型的包装器:

int func2(std::function<int(int)> funcptr2) {
  return funcptr2(2);
}
int func1(std::function<int(int,int,int)> funcptr1) {
  return func2(
    [funcptr1](int i)->int {
      return funcptr1(i,8,9);
    }
  );
}

您还可以使用模板使您的函数适用于任何可调用类型:

template <typename F>
int func2(F funcptr2) {
  return funcptr2(2);
}
template <typename F>
int func1(F funcptr1) {
  return func2(
    [funcptr1](int i)->int {
      return funcptr1(i,8,9);
    }
  );
}

【讨论】:

    【解决方案3】:

    在 C 中,你不能。您必须传递函数指针和两个参数。

    在 C++ 中,您可以使用 std::bind(或旧版本中的 boost::bind)来实现此目的。

    【讨论】:

      猜你喜欢
      • 2020-11-08
      • 2021-12-18
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 2013-03-16
      • 2015-01-29
      • 1970-01-01
      • 2012-11-28
      相关资源
      最近更新 更多