简体   繁体   English

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

[英]In C++ what does it mean for a compiler to “inline” a function object?

In the wikipedia article about function objects it says such objects have performance advantages when used with for_each because the compiler can "inline" them. 在wikipedia 关于函数对象的文章中,它说这些对象在与for_each一起使用时具有性能优势,因为编译器可以“内联”它们。

I'm a bit foggy on exactly what this means in this context... or any context I'm embarrassed to say. 我对这在这种情况下的意义有点模糊......或者我不好意思说的任何背景。 Thanks for any help! 谢谢你的帮助!

The last parameter of for_each template is a functor . for_each模板的最后一个参数是一个仿函数 Functor is something that can be "called" using the () operator (possibly with arguments). Functor是可以使用()运算符(可能带参数)“调用”的东西。 By defintion, there are two distinctive kinds of functors: 根据定义,有两种不同的仿函数:

  1. Ordinary non-member functions are functors. 普通的非会员功能是仿函数。
  2. Objects of class type with overloaded () operator (so called function objects ) are also functors. 具有重载()运算符(所谓的函数对象 )的类类型的对象也是仿函数。

Now, if you wanted to use an ordinary function as a functor for for_each , it would look something like the following 现在,如果你想使用普通函数作为for_each的函子,它将类似于以下内容

inline void do_something(int &i) { /* do something */ }

int main() {
  int array[10];
  std::for_each(array, array + 10, &do_something);
}

In this case the for_each template is instantiated with [deduced] arguments <int *, void (*)(int &)> . 在这种情况下, for_each模板使用[推导]参数<int *, void (*)(int &)>实例化。 Note that the actual functor value in this case is the function pointer &do_something passed as the function argument. 请注意,在这种情况下,实际的函子值是作为函数参数传递的函数指针&do_something From the point of view of for_each function this is a run-time value. for_each函数的角度来看,这是一个运行时值。 And since it is a run-time value, the calls to the functor cannot be inlined. 由于它是一个运行时值,因此无法内联对仿函数的调用。 (Just like it is in general case impossible to inline any call made through a function pointer). (就像通常情况下无法内联通过函数指针进行的任何调用一样)。

But if we use a function object instead, the code might look as follows 但是,如果我们使用函数对象,代码可能如下所示

struct do_something {
  void operator()(int &i) { /* do something */ }
}; 

int main() {
  int array[10];
  std::for_each(array, array + 10, do_something());
}

In this case the for_each template is instantiated with [deduced] arguments <int *, do_something> . 在这种情况下, for_each模板使用[推导]参数<int *, do_something>实例化。 The calls to the functor from inside for_each will be directed to do_something::operator() . for_each内部调用functor将被定向到do_something::operator() The target for the call is known and fixed at compile-time. 调用的目标是已知的,并在编译时修复。 Since the target function is known at compile-time, the call can easily be inlined. 由于目标函数在编译时是已知的,因此可以很容易地内联调用。

In the latter case we, of course, also have a run-time value passed as an argument to for_each . 在后一种情况下,我们当然也有一个运行时值作为for_each的参数传递。 It is a [possibly "dummy" temporary] instance of do_something class we create when we call for_each . 它是我们在调用for_each时创建的do_something类的[可能“虚拟”临时]实例。 But this run-time value has no effect on the target for the call (unless the operator () is virtual), so it doesn't affect inlining. 但是此运行时值对调用的目标没有影响(除非operator ()是虚拟的),因此它不会影响内联。

Inline is the process a compiler can replace a call to a function with the contents of the function itself. 内联是编译器可以用函数本身的内容替换对函数的调用的过程。 It requires the compiler to know the contents of the function when it's being compiled. 它要求编译器在编译时知道函数的内容。

The compiler often can't do this if a function pointer is passed. 如果传递函数指针,编译器通常不能这样做。

Inlining just means replacing every call to that function with the body of that function directly. 内联只是意味着直接用该函数的主体替换对该函数的每个调用。

It's an optimization for small functions because it reduces the overhead of jumping to a new function and then returning. 它是小功能的优化,因为它减少了跳转到新功能然后返回的开销。

It means that the function's definition (code) may be copied and saving you from a function call (which is considered to be expensive on some systems). 这意味着可以复制函数的定义(代码)并将其从函数调用中保存(在某些系统上被认为是昂贵的)。 Think of macro replacement. 想想宏替换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM