1.2.4.1 Basic

  1. In C language, we use function pointer.
    int(*pf)(int, int); //declare a pointer function 
    int fun1(int i,int j); 
    pf = fun1 // or pf=&fun1; we usually skip &. 
    (*pf)(1,2) //or pf(1,2);
  2. In C++, Some generic algorithms can also accept function.
    void fun(int i) { 
      //do stuff 
    } 
    //here just input fun name, its function pointer usage 
    for_each(a.begin(), a.end(), fun);
  3. But passing function has shortcomings 1) Can’t be inline. 2) sometimes It can’t be compile due to different compiler implementation. 3) You can’t adapt or custom it. So STL invented a functor(function object). It is class or structure objects for which the () operator is overloaded.
    class functor { // also call function objects 
    public: 
      void operator()(int i); 
    }; 
    //here, use functor, (class object); 
    //overload operator(); 
     
    for_each(a.begin(), a.end(), functor()); 
    // You must use functor() 
    //with () to produce a temporary functor obj.
  4. You can use struct or class. If you want to have a private customized value, you have to use class to build a functor. Such as cutoff value in below code.
    // you can use class instead struct, but you need to make 
    //operator() public, in struct, default is public, so struct is better! 
    struct less_than_7 : std::unary_function<int, bool>{ 
        bool operator()(int i) const { return i < 7; } 
    }; 
     
    class less_than_value : std::unary_function<int, bool>{ 
        less_than_value(int x) :value(x) {}; 
        bool operator()(int i) const { return i < value; } 
        private: 
        int value; 
    }; 
     
    std::count_if(v.begin(), v.end(), std::not1(less_than_7()));
  5. In previous example, you can see advantage of usage less_than_value.
    1. You can inherit from template unary_function when you declare a functor, then you functor is adaptable by bind1().
    2. But if you want to have a cutoff value, You can use class to make cutoff value as private.
    3. set or map are template class. So it only accept type, not function, If you want to give set or map a customized compare function, you have to use functor to define a type.
         class yanCompare{ 
           bool operator()(string &s1, string &s2){....;} 
           }; 
       
           set<string, yanCompare> setDic; 
           //yanCompare cant be a function. 
           // in set, just yanCompare, no () follow it. 
           //Its a type. not obj. 
       
           remove_if(...yanComare() ); 
           // in some algorithm, you have to use yanCompare() 
           // to produce a function obj.
  6. Sometimes, you don’t want to reuse this functor which will cause you write clutter code, so C++14 introduce lambda. Detail can be seen in C++ 11 New features.
     []->bool(int){return x<7}; 
     // if only return, you can omit ->bool (return type); 
    std::count_if(v.begin(), v.end(), [](int x){return x<7;} );
  7. Why you use unary_funciton and binary_function template, then inherit from it. It can make you functor adaptable, see below section: