Чтобы устранить неправильное представление о том, что компилятор может встроить, достаточно хороший компилятор может встроить указатели на функции. Он может просто встроить функциональные объекты, так как доступно больше статической информации. Например, указатель на функцию, которая не принимает параметров и возвращает bool, имеет тип bool (*) (), в то время как функтор имеет явный тип, а именно, функтор, и создание экземпляра шаблона может статически вызывать оператор функтора, а не чем вызов через указатель на функцию.
На практике, однако, это в основном вопрос предоставления компилятору достаточно информации для эффективной оптимизации.
Например, Visual C ++ 2008, учитывая следующий код с полной оптимизацией:
#include "stdafx.h"
#include <algorithm>
const char print_me[]= "hello!";
class print_functor
{
public:
void operator()(char c)
{
printf("%c", c);
}
};
void print_function(char c)
{
printf("%c", c);
}
int _tmain(int argc, _TCHAR* argv[])
{
std::for_each(print_me, print_me + sizeof(print_me)/sizeof(print_me[0]), print_functor());
printf("\n");
std::for_each(print_me, print_me + sizeof(print_me)/sizeof(print_me[0]), print_function);
return 0;
}
полностью включает оба std::for_each
звонка. Кстати, на ПК первый for_each имеет ненужный lea ecx, [ecx]
.