与以值作为参数的普通函数相比,函子的区别是什么?

What is distinctive for functors compared to normal functions taking values as arguments

本文关键字:是什么 区别 参数 函数      更新时间:2023-10-16

我是这个概念的新手,但是当我搜索函数的区别和好处时,它们能够在内部存储值并从构造中初始化这些值,但正常函数也以相同的方式工作,除了它们在函数调用时将所有参数作为整体。很可能我在某些方面是错的但是函数函数相对于普通函数的好处和窍门在哪里呢

核心区别在于,函函数定义的是类型,而不是函数。即使是无状态函子(没有任何附加数据)也可以利用这一点。例如,考虑在排序算法中使用std::less:

template <typename Iterator, typename Comparator>
sort(Iterator begin, Iterator end, Comparator c) {
...
   if (c(*begin,*end)) { ...
...
}

称为sort(v.begin(), v.end(), std::less<int>());。当函数被调用时,std::less<int>的一个实例被创建并传递给模板。因为它是无状态的,所以传递函数的成本几乎为零。在函数内部,调用c(a,b)被确定为对c.operator()(a,b)的调用,并且编译器知道其类型。它可以有效地内联调用(在这种情况下非常简单),并用单个比较指令替换它。

另一方面,等效的C函数qsort接受一个函数指针(不能按值传递函数)。在qsort内部,编译器不知道调用的函数是什么,它不能内联它,所以它必须为每次比较执行一个函数调用。

函子既可以添加额外的信息,以后可以在调用的地方使用(这对于普通函数来说是不可能的),也可以传递额外的信息,比如提供需要调用的信息(可以获得相同的行为,但对性能有影响)或其他附加信息(类型可以有嵌套的类型/类型定义,用于特征检查的信息…)

普通函数,独立函数或成员函数,只有在调用函数时传递的参数。因此,没有办法向函数传递额外的数据。

这与函子不同。functor是对象的实例,因此确实可以存储传递给其构造函数的数据(在传递functor时使用构造函数)。

在c++ 11中,事情有点混乱,因为lambdas也可以通过使用capture来"存储"(不是技术上正确的词)值。或者使用std::bind,它允许您在实际调用可调用对象时将值绑定为参数。