указатель функции против функторов в C++
В чем разница между использованием функторов и указателей функций?
Например
//Functor
struct add_x
{
int x;
add_x(int y):x(y){}
int operator()(int y)
{
return x+y;
}
};
//Function
int (func)(int x)
{
return ++x;
}
std::vector<int> vec();
//fill vec with 1 2 3 4 5
int (*f)(int) = func;//Function pointer
std::transform(vec.begin(),vec.end(),f); //approach 1
std::transform(vec.begin(),vec.end(),add_x(1)); //approach 2
Оба подхода работают, но я уверен, что будут случаи, когда один предпочтительнее(или возможен), чем другой.
2 ответов:
Во-первых, функтор может содержать внутреннее состояние; состояние, допустимое только дляэтого вызова объекта функции. Вы можете добавить переменные
staticв свою функцию, но они будут использоваться для любого вызова функции.Во-вторых, компилятор может инлайн-вызовы функтора; он не может сделать то же самое для указателя функции. Вот почему C++
std::sort()бьет дерьмо из Cqsort()с точки зрения производительности.
Функторы могут даже использоваться для эмуляции лямбда-выражений (если вам нужно использовать более старый компилятор до C++11/C++14) в определенной степени, потому что они могут иметь индивидуальное состояние (например, как переменные-члены).
struct A { int x; // state member can even be made private! Instance per functor possible int operator()(int y) { return x+y } };Или как лямбда
Указатели функций могут получать только аргументы, но не имеют состояния, если они не обращаются к каким-либо глобальным переменным (что действительно плохо и опасно).auto lambda = [&x](int y) { return x+y };// global scope, anyone can accidentally manipulate and not thread-safe here, only one global instance possible! inx x; int (func)(int y) { return x+y };
Comments