在维基百科article about function objects中,它说这些对象在与 for_each 一起使用时具有性能优势,因为编译器可以“内联”它们。
我对这在这种情况下的意义有点模糊......或者我不好意思说的任何背景。谢谢你的帮助!
答案 0 :(得分:14)
for_each
模板的最后一个参数是仿函数。 Functor 是可以使用()
运算符(可能带参数)“调用”的东西。根据定义,有两种不同的仿函数:
()
运算符的类类型对象(所谓的函数对象)也是仿函数。现在,如果您想将普通函数用作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)
这意味着可以复制函数的定义(代码)并将其从函数调用中保存(在某些系统上被认为是昂贵的)。想想宏替换。