The last parameter of for_each
template is a functor. Functor is something that can be "called" using the ()
operator (possibly with arguments). By defintion, there are two distinctive kinds of functors:
- Ordinary non-member functions are
functors.
- 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
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 &)>
. Note that the actual functor value in this case is the function pointer &do_something
passed as the function argument. From the point of view of for_each
function this is a run-time value. 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>
. The calls to the functor from inside for_each
will be directed to 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
. It is a [possibly "dummy" temporary] instance of do_something
class we create when we call for_each
. 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.