函子调用和函数调用之间的详细区别? [英] Detailed difference between functor's call and function call?

查看:170
本文介绍了函子调用和函数调用之间的详细区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


这个工作的关键原因是for_each()实际上并不认为
它的第三个参数是一个函数。
它简单地假设它的第三个
参数是可以通过适当的参数调用的
。 A
适当定义的对象还有
as - 并且通常比 - a
函数更好。例如,
内联
类的应用程序操作符比内联函数传递
作为函数的指针更容易。
因此,函数对象
的执行速度比普通的
函数快。一个类的
应用程序操作符(§11.9)的对象是
称为函数对象,
函子或简单的函数对象。

[Stroustrup,C ++ 3rd edition,18.4-last段落]

[Stroustrup, C++ 3rd edition, 18.4-last paragraph]


  1. 我一直认为运算符
    ()
    调用就像函数调用
    在运行时。与
    a正常函数调用有什么不同?

  1. I always thought that the operator ( ) call is just like function call at runtime. how does it differ from a normal function call?

为什么比正常的$ b $更容易内联
应用程序操作符b函数?

Why is it easier to inline the application operator than a normal function?

它们如何比函数
调用更快?

How are they faster than function call?


推荐答案

通常,函数传递给模板函数 - 如果你这样做,你传递一个真实函数(即一个函数指针)或一个函子(即一个具有重载 operator()的类)。基本上,两者都有一个函数调用操作符,因此是编译器可以实例化 for_each 模板的有效模板参数。 这意味着 for_each 要使用传递的函数的具体类型实例化,或者使用特定的类型的函数指针传递。在这个专业化中,函数指针的性能优于函数指针。

Generally, functors are passed to templated functions - if you're doing so, then it doesn't matter if you pass a "real" function (i.e. a function pointer) or a functor (i.e. a class with an overloaded operator()). Essentially, both have a function call operator and are thus valid template parameters for which the compiler can instantiate the for_each template. That means for_each is either instantiated with the specific type of the functor passed, or with the specific type of function pointer passed. And it's in that specialization that it is possible for functors to outperform function pointers.

毕竟,如果你传递一个函数指针,那么参数的编译类型只是一个函数指针。如果 for_each 本身没有内联,那么这个特殊的 for_each 实例被编译为调用一个不透明的函数指针 - 编译器如何内联函数指针?它只是知道其类型,而不是 该类型的函数实际上是通过 - 至少,除非它可以在优化时使用非本地信息,这是更难做。

After all, if you're passing a function pointer, then the compile-type type of the argument is just that - a function pointer. If for_each itself is not inlined, then this particular for_each instance is compiled to call an opaque function pointer - after all, how could the compiler inline a function pointer? It just knows its type, not which function of that type is actually passed - at least, unless it can use non-local information when optimizing, which is harder to do.

但是,如果您传递函子,那么函子的编译时类型将用于实例化 for_each 模板。这样做,你可能传递一个简单的非虚拟类,只有一个实现的适当的 operator()。因此,当编译器遇到对 operator()的调用时,它会确切知道哪个实现是该函数的唯一实现 - 现在它可以内联。

However, if you pass a functor, then the compile-time type of that functor is used to instantiate the for_each template. In doing so, you're probably passing a simple, non-virtual class with only one implementation of the appropriate operator(). So, when the compiler encounters a call to operator() it knows exactly which implementation is meant - the unique implementation for that functor - and now it can inline that.

如果你的函子使用虚方法,潜在的优势就会消失。而且,当然,函子是一个类,你可以用它来做各种其他低效的事情。但是对于基本情况,这就是为什么编译器更容易优化&

If your functor uses virtual methods, the potential advantage disappears. And, of course, a functor is a class with which you can do all kinds of other inefficient things. But for the basic case, this is why it's easier for the compiler to optimize & inline a functor call than a function pointer call.

函数指针不能被内联,因为while编译 for_each 编译器只有
类型的函数而不是函数的标识。相比之下,函子可以内联,因为即使编译器只有函数类型,类型通常足以唯一标识函子 operator()方法。

Function pointers can't be inlined since while compiling for_each the compiler has only the type of the function and not the identity of the function. By contrast, functors can be inlined since even though the compiler only has the type of functor, the type generally suffices to uniquely identify the functor's operator() method.

这篇关于函子调用和函数调用之间的详细区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆