与以值作为参数的普通函数相比,函子的区别是什么?
What is distinctive for functors compared to normal functions taking values as arguments
我是这个概念的新手,但是当我搜索函数的区别和好处时,它们能够在内部存储值并从构造中初始化这些值,但正常函数也以相同的方式工作,除了它们在函数调用时将所有参数作为整体。很可能我在某些方面是错的但是函数函数相对于普通函数的好处和窍门在哪里呢
核心区别在于,函函数定义的是类型,而不是函数。即使是无状态函子(没有任何附加数据)也可以利用这一点。例如,考虑在排序算法中使用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)
的调用,并且编译器知道其类型。它可以有效地内联调用(在这种情况下非常简单),并用单个比较指令替换它。
qsort
接受一个函数指针(不能按值传递函数)。在qsort
内部,编译器不知道调用的函数是什么,它不能内联它,所以它必须为每次比较执行一个函数调用。
函子既可以添加额外的信息,以后可以在调用的地方使用(这对于普通函数来说是不可能的),也可以传递额外的信息,比如提供需要调用的信息(可以获得相同的行为,但对性能有影响)或其他附加信息(类型可以有嵌套的类型/类型定义,用于特征检查的信息…)
普通函数,独立函数或成员函数,只有在调用函数时传递的参数。因此,没有办法向函数传递额外的数据。
这与函子不同。functor是对象的实例,因此确实可以存储传递给其构造函数的数据(在传递functor时使用构造函数)。
在c++ 11中,事情有点混乱,因为lambdas也可以通过使用capture来"存储"(不是技术上正确的词)值。或者使用std::bind
,它允许您在实际调用可调用对象时将值绑定为参数。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 这些情况有什么区别?我怎么知道什么是临时对象?
- 如果我提前将参数声明为变量而不是将它们内联写入函数调用,那有什么区别(在内存方面)?
- C++和Python之间平等含义的区别的根源是什么?
- 尾随空格是什么意思,它和空白有什么区别?
- 调试构建和发布构建、区别和用途是什么意思
- std::ifstream::in 和 std::ios::in 有什么区别?(显然是 C++ 中 std::ifstr
- 在 C++ STL 的比较函数中使用"<="符号而不是"<"符号有什么区别?
- 在头中声明变量而不是在源文件(cpp/h)中声明变量有什么区别
- "Thing thing;"和"Thing thing = Thing();"有什么区别,什么时候应该使用一个而不是另一个?
- 如果 a 是 cv::Mat 和 cv::Mat b=a.row(1),那么两个 cv::Mat 实例有什么区别
- 如果f是双精度数,f+=1和f+=1.0有什么区别吗?
- char和CString的区别和关系是什么?
- 那么,是什么区别了template(c.end(),_1)和template_back(_1)呢
- C++:按变量值而不是数字移位 ->有什么区别?