Ответ 1
Последний параметр шаблона 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
. Это [возможно "dummy" временный] экземпляр класса do_something
, который мы создаем, когда вызываем for_each
. Но это значение времени выполнения не влияет на цель для вызова (если только operator ()
не является виртуальным), поэтому он не влияет на inlining.