C++ 在C++;对于编译器来说,“编译”意味着什么;内联“;函数对象?

C++ 在C++;对于编译器来说,“编译”意味着什么;内联“;函数对象?,c++,functor,function-object,C++,Functor,Function Object,在维基百科中,它说这样的对象与for_一起使用时具有性能优势,因为编译器可以“内联”它们 我有点不明白在这种情况下这到底意味着什么。。。或者任何我不好意思说的上下文。谢谢你的帮助 内联仅仅意味着直接用函数体替换对该函数的每个调用 这是对小函数的优化,因为它减少了跳转到新函数然后返回的开销。这意味着可以复制函数的定义(代码),从而避免函数调用(在某些系统上被认为是昂贵的)。想想宏替换。内联是编译器可以用函数本身的内容替换函数调用的过程。 它要求编译器在编译函数时知道函数的内容 如果传递函数指针,编

在维基百科中,它说这样的对象与for_一起使用时具有性能优势,因为编译器可以“内联”它们


我有点不明白在这种情况下这到底意味着什么。。。或者任何我不好意思说的上下文。谢谢你的帮助

内联仅仅意味着直接用函数体替换对该函数的每个调用


这是对小函数的优化,因为它减少了跳转到新函数然后返回的开销。

这意味着可以复制函数的定义(代码),从而避免函数调用(在某些系统上被认为是昂贵的)。想想宏替换。

内联是编译器可以用函数本身的内容替换函数调用的过程。 它要求编译器在编译函数时知道函数的内容


如果传递函数指针,编译器通常无法执行此操作。

每个模板的
的最后一个参数是一个函子。Functor是可以使用
()
运算符(可能带有参数)进行“调用”的对象。根据定义,有两种不同类型的函子:

  • 普通的非成员函数是 函子
  • 带有重载
    ()
    运算符的类类型的对象(所谓的函数对象)也是函子
  • 现在,如果您想使用普通函数作为每个
    的函子,它将如下所示

    inline void do_something(int &i) { /* do something */ }
    
    int main() {
      int array[10];
      std::for_each(array, array + 10, &do_something);
    }
    
    在这种情况下,每个
    模板的
    都用[推导]参数
    实例化。请注意,本例中的实际函子值是作为函数参数传递的函数指针
    &do\u something
    。从每个函数的
    角度来看,这是一个运行时值。而且,由于它是一个运行时值,对函子的调用不能内联。(就像一般情况下不可能通过函数指针内联任何调用一样)

    但是如果我们使用函数对象,代码可能如下所示

    struct do_something {
      void operator()(int &i) { /* do something */ }
    }; 
    
    int main() {
      int array[10];
      std::for_each(array, array + 10, do_something());
    }
    
    在这种情况下,每个
    模板的
    都用[推导]参数
    实例化。从内部对每个
    的functor的调用将被定向到
    do\u something::operator()
    。调用的目标在编译时已知并固定。由于目标函数在编译时已知,因此调用可以很容易地内联


    当然,在后一种情况下,我们还将一个运行时值作为参数传递给每个
    。它是我们为每个调用
    时创建的
    do\u something
    类的[可能是“虚拟”临时]实例。但是这个运行时值对调用的目标没有影响(除非
    操作符()
    是虚拟的),因此它不会影响内联。

    但是编译器可以使用
    ::std::for_each
    的完整定义。对于智能编译器,它应该看到调用它时使用了一个特定的参数,该参数恰好是内联声明的函数的地址。编译器应该能够像类方法一样内联函数调用。@Omnifarious:在我的示例中,您可以为每个
    调用
    ,不同的函数具有
    void(int&)
    签名,编译器被迫使用相同的签名,每个
    都有一个且仅有一个
    的实例化:
    每个示例(忘记模板),当我的程序中有函数
    void foo(int)
    并多次调用它作为
    foo(1);富(2),;傅(3)我通常希望编译器为
    foo
    生成一个函数体,并使用不同的参数执行相同的函数体:1、2和3。如果我发现编译器分别用“内联”常量1、2和3生成了3个不同的
    foo
    ,我会感到非常惊讶。对于较小的
    foo
    来说,这是可以的(如果之后它是内联的),但是对于较大的
    foo
    来说,这是不可取的。你所描述的基本上是一样的。@AndreyT:噢!给他一记耳光是有道理的。这也很愚蠢,但你是对的,只能这样,没有办法。不过我知道一个解决办法。大grin一个函数指针模板参数,导致类型名称包含要使用的函数。模板的运算符()只是转发给作为模板参数传递的函数。@Omnifarious:是的,完全正确!函数指针作为模板参数确实可以工作,并且不需要额外的内联工作。但是在
    std::for_each
    的情况下,函数指针本身就是函数参数(不是模板参数)。模板参数是函数指针类型。