указатель функции против функторов в 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


Оба подхода работают, но я уверен, что будут случаи, когда один предпочтительнее(или возможен), чем другой.
617   2  

2 ответов:

Во-первых, функтор может содержать внутреннее состояние; состояние, допустимое только дляэтого вызова объекта функции. Вы можете добавить переменные static в свою функцию, но они будут использоваться для любого вызова функции.

Во-вторых, компилятор может инлайн-вызовы функтора; он не может сделать то же самое для указателя функции. Вот почему C++ std::sort() бьет дерьмо из C qsort() с точки зрения производительности.

Функторы могут даже использоваться для эмуляции лямбда-выражений (если вам нужно использовать более старый компилятор до 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

    Ничего не найдено.