最后一个参数为for_each
模板是一个functor. 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 ()
是虚拟的),所以它不影响内联。