在C ++中,编译器“内联”一个函数对象意味着什么?

时间:2010-02-08 23:21:08

标签: c++ functor function-object

在维基百科article about function objects中,它说这些对象在与 for_each 一起使用时具有性能优势,因为编译器可以“内联”它们。

我对这在这种情况下的意义有点模糊......或者我不好意思说的任何背景。谢谢你的帮助!

4 个答案:

答案 0 :(得分:14)

for_each模板的最后一个参数是仿函数 Functor 是可以使用()运算符(可能带参数)“调用”的东西。根据定义,有两种不同的仿函数:

  1. 普通的非会员职能是 函子。
  2. 具有重载()运算符的类类型对象(所谓的函数对象)也是仿函数。
  3. 现在,如果您想将普通函数用作for_each的仿函数,它将类似于以下内容

    inline void do_something(int &i) { /* do something */ }
    
    int main() {
      int array[10];
      std::for_each(array, array + 10, &do_something);
    }
    

    在这种情况下,for_each模板使用[推导的]参数<int *, void (*)(int &)>进行实例化。请注意,在这种情况下,实际的函子值是作为函数参数传递的函数指针&do_something。从for_each函数的角度来看,这是一个运行时值。由于它是一个运行时值,因此无法内联对仿函数的调用。 (就像通常情况下不可能内联通过函数指针进行的任何调用一样)。

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

    struct do_something {
      void operator()(int &i) { /* do something */ }
    }; 
    
    int main() {
      int array[10];
      std::for_each(array, array + 10, do_something());
    }
    

    在这种情况下,for_each模板使用[推导的]参数<int *, do_something>进行实例化。从for_each内部对仿函数的调用将定向到do_something::operator()。调用的目标是已知的,并在编译时修复。由于目标函数在编译时是已知的,因此可以很容易地内联调用。

    在后一种情况下,我们当然也将运行时值作为参数传递给for_each。它是我们在调用do_something时创建的for_each类的[可能“虚拟”临时]实例。但是这个运行时值对调用的目标没有影响(除非operator ()是虚拟的),所以它不会影响内联。

答案 1 :(得分:6)

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

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

答案 2 :(得分:3)

内联只是意味着直接用该函数的主体替换对该函数的每个调用。

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

答案 3 :(得分:3)

这意味着可以复制函数的定义(代码)并将其从函数调用中保存(在某些系统上被认为是昂贵的)。想想宏替换。