gpt4 book ai didi

c++ - 仿函数调用和函数调用的详细区别?

转载 作者:IT老高 更新时间:2023-10-28 22:59:51 24 4
gpt4 key购买 nike

The key reason this works is that for_each () doesn’t actually assume its third argument to be a function. It simply assumes that its third argument is something that can be called with an appropriate argument. A suitably defined object serves as well as – and often better than – a function. For example, it is easier to inline the application operator of a class than to inline a function passed as a pointer to function. Consequently, function objects often execute faster than do ordinary functions. An object of a class with an application operator (§11.9) is called a functionlike object, a functor, or simply a function object.

[Stroustrup,C++ 第 3 版,18.4-最后一段]

  1. 我一直以为运算符( ) 调用就像函数调用在运行时。它与正常的函数调用?

  2. 为什么内联更容易 应用程序运算符比正常 功能?

  3. 它们如何比函数更快 打电话?

最佳答案

一般来说,仿函数被传递给 模板化 函数 - 如果你这样做,那么传递一个“真实”函数(即函数指针)或仿函数 (即具有重载 operator() 的类。本质上,两者都有一个函数调用运算符,因此是编译器可以为其实例化 for_each 模板的有效模板参数。 这意味着 for_each 要么使用传递的仿函数的特定 type 进行实例化,要么使用传递的函数指针的特定 type 进行实例化。 正是在这种特殊化中,仿函数有可能胜过函数指针。

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

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

如果你的仿函数使用虚方法,潜在的优势就消失了。当然,仿函数是一个类,你可以用它做各种其他低效的事情。但对于基本情况,这就是编译器优化和内联仿函数调用比函数指针调用更容易的原因。

总结

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

关于c++ - 仿函数调用和函数调用的详细区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3938321/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com