C++ 在C++;对于编译器来说,“编译”意味着什么;内联“;函数对象?
在维基百科中,它说这样的对象与for_一起使用时具有性能优势,因为编译器可以“内联”它们C++ 在C++;对于编译器来说,“编译”意味着什么;内联“;函数对象?,c++,functor,function-object,C++,Functor,Function Object,在维基百科中,它说这样的对象与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
的情况下,函数指针本身就是函数参数(不是模板参数)。模板参数是函数指针类型。