1.5.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 std::not1.
    2. you can change value when you build a less_than_value functor.
    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; 
      //just yanCompare, no() follow it. pass into a type, not obj 
       
       
      remove_if(...yanComare() ); 
      //yanCompare(), to pass a function obj.
  6. Based on previous example, I would like to say something about type, variable, expression, value.
    1. type is build-in type, custom type(class, struct), and pointer, reference type.
    2. variable has a name and value,
    3. expression has no name but has value,
    4. value can be divided by three categories, can overload move ctor.
  7. template function is a function, we have to input value, so we pass variable or expression. in previous example, yanCompare() produce a obj variable.
  8. template container need type. so we have to input type, so we input yanCompare, It’s a class type.
  9. Given a variable or expression, we need to know its type, we can use auto, T in template and decltype. detail can be seen "type inference" section.
  10. Given a container, we can get value_type by predefined type information in container.
  11. given a type, we need to define an variable, we can use typedef or using alias to replace complex type in C++(such as: vect<pair<string, int> >). In template,
  12. In template class, If you define depended type, use using alias, detail can be seen in using alias part in the last chapter.
  13. 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;} );
  14. Why you use unary_funciton and binary_function template, then inherit from it. It can make you functor adaptable, see below section: