【问题标题】:Why do we use std::function in C++ rather than the original C function pointer? [duplicate]为什么我们在 C++ 中使用 std::function 而不是原来的 C 函数指针? [复制]
【发布时间】:2012-07-06 08:46:21
【问题描述】:

std::function<T1(T2)> 比原来的T1 (*)(T2) 有什么优势?

【问题讨论】:

  • 它更通用,但速度也较慢。您无法比较 ::std::function 实例,它从堆中分配。
  • @user1095108:它可以从堆中分配。就像“小 string 优化”一样,实现可能会使用“小 function 优化”。
  • may... 有时是徒劳的希望。
  • 可能还有一个缺点。

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


【解决方案1】:

std::function可以容纳多个函数指针,即functors

#include <functional>

void foo(double){}

struct foo_functor{
  void operator()(float) const{}
};

int main(){
  std::function<void(int)> f1(foo), f2((foo_functor()));
  f1(5);
  f2(6);
}

Live example on Ideone.

如示例所示,您也不需要完全相同的签名,只要它们兼容(即,std::function 的参数类型可以传递给包含的函数 /函子)。

【讨论】:

  • 另外,使用std::bind 可以创建委托(即用对象封装成员函数指针)并将它们存储在 std::function 中,创建后的处理没有任何区别。这是单独的函数指针无法做到的。
  • @fish: 嗯,std::bind 返回的是一个函子,所以我不会真的特例。可以看到的特殊之处在于,您可以只传递一个成员函数指针,std::function 将使其像f(object, param); 一样可调用。 Example on Ideone
  • 另一件事是(可以说)更容易声明。函数指针声明有点难以遵循,因为它们的 C 继承了 “声明反映用法” 规则。 std::function 对象的声明看起来更像函数声明。 (对不起,我真的应该进行编辑,但我看到该帖子目前仍在频繁更新。请随意合并)。
  • 是的,当然可以。我认为值得一提,因为委托是许多语言中的常见模式,这使得在 C++ 中流畅地复制它们成为可能。
  • 事实上,程序编译但不执行任何操作。我可以建议cout 函数和函子中的参数吗?而且我还会使用非整数参数添加一个调用,例如f1(4.7);。这将显示将接受double 的函数存储到接受int 参数的std::function 中的效果。我还将输出包含在答案中。我已经准备好了修改后的代码on Ideone。如果您同意,我可以自己编辑您的答案,但只有在您允许的情况下才会这样做。
【解决方案2】:

std::function 可以保存函数对象(包括 lambda),以及具有正确签名的函数指针。所以它更通用。

【讨论】:

  • 附带问题:我假设 lambda 是虚拟调用的,对吧?
  • @Mehrdad:你对所谓的虚拟的定义是什么?
  • @DavidRodríguez-dribeas:间接调用,例如 virtual 函数。
  • @Mehrdad: @Mehrdad: std::function&lt;&gt; 需要添加一个间接来执行类型擦除,所以是的,有一个额外的间接级别通过std::function 调用 lambda(好吧,调用 lambda 或任何其他事情通过std::function)
  • @anthropomorphic: 不,virtual 表示它在派生类中可覆盖
【解决方案3】:

除了更简洁的外观和更具描述性的语法外,std::function 可以存储任何可调用对象:

  • 功能
  • lambda 表达式
  • 绑定表达式
  • 函子

更不用说存储、复制和绑定对象到成员函数更容易和更直观。

【讨论】:

  • 绑定表达式只返回函子,因此列出函子和绑定表达式是多余的。
猜你喜欢
  • 2019-02-16
  • 2014-11-09
  • 2015-03-10
  • 2012-11-19
  • 2014-02-17
  • 2021-12-22
  • 1970-01-01
  • 2017-08-27
  • 2013-09-13
相关资源
最近更新 更多