在关于函数对象的维基百科文章中,它说这些对象在与for_each一起使用时具有性能优势,因为编译器可以“内联”它们。
我对这在这种情况下的确切含义有点模糊......或者我不好意思说的任何情况。谢谢你的帮助!
在关于函数对象的维基百科文章中,它说这些对象在与for_each一起使用时具有性能优势,因为编译器可以“内联”它们。
我对这在这种情况下的确切含义有点模糊......或者我不好意思说的任何情况。谢谢你的帮助!
for_each
模板的最后一个参数是仿函数。函子是可以使用()
运算符(可能带有参数)“调用”的东西。根据定义,有两种不同的函子:
()
(所谓的函数对象)也是函子。现在,如果你想使用一个普通函数作为 的函子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
模板是用 [deduced] arguments 实例化的<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
模板是用 [deduced] arguments 实例化的<int *, do_something>
。从内部对函子的调用for_each
将被定向到do_something::operator()
. 调用的目标是已知的并在编译时固定。由于目标函数在编译时是已知的,因此可以轻松内联调用。
在后一种情况下,我们当然也有一个运行时值作为参数传递给for_each
. 它是do_something
我们调用时创建的类的[可能是“虚拟”临时]实例for_each
。但是这个运行时值对调用的目标没有影响(除非operator ()
是虚拟的),所以它不会影响内联。
内联是编译器可以用函数本身的内容替换对函数的调用的过程。它要求编译器在编译时知道函数的内容。
如果传递了函数指针,编译器通常无法执行此操作。
内联只是意味着直接用该函数的主体替换对该函数的每个调用。
这是对小函数的优化,因为它减少了跳转到新函数然后返回的开销。
这意味着函数的定义(代码)可能会被复制并让您免于函数调用(这在某些系统上被认为是昂贵的)。考虑宏替换。