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