указатель функции против функторов в 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()
выбивает дерьмо из 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 };