STL学习笔记----8.STL仿函数

 

一. 概念:

函数对象function objects,又名仿函数,是一个定义了operator()操作对象

  1. class FunctionObjectType { 
  2.      public
  3.        void operator() { 
  4.            statements 
  5.        } 
  6. }; 
class FunctionObjectType {
     public:
       void operator() {
           statements
       }
};

二. 仿函数当做排序准则:

程序员经常需要将某些class object以已序的形式放到容器中,然而有时你无法使用一般的operator<来对这些对象排序,这时可以仿函数。

  1. #include <iostream> 
  2. #include <string> 
  3. #include <set> 
  4. #include <algorithm> 
  5. using namespace std; 
  6.  
  7. class Person { 
  8.      public
  9.        string firstname() const
  10.        string lastname() const
  11.        ... 
  12. }; 
  13.  
  14. /*  仿函数,按名字排序
  15. * - operator() returns whether a person is less than another person
  16. */ 
  17. class PersonSortCriterion { 
  18.      public
  19.        bool operator() (const Person& p1, const Person& p2) const
  20.            /* a person is less than another person
  21.             * - if the last name is less
  22.             * - if the last name is equal and the first name is less
  23.             */ 
  24.            return p1.lastname()<p2.1astname() || 
  25.                   (! (p2.1astname()<p1.lastname()) && 
  26.                    p1.firstname()<p2.firstname()); 
  27.        } 
  28. }; 
  29.  
  30. int main() 
  31.        //声名 set ,用这个仿函数 
  32.        typedef set<Person,PersonSortCriterion> PersonSet; 
  33.  
  34.        //create such a collection 
  35.        PersonSet coll; 
  36.        ... 
  37.  
  38.        //do something with the elements 
  39.        PersonSet::iterator pos; 
  40.        for (pos = coll.begin(); pos != coll.end();++pos) { 
  41.            ... 
  42.        } 
  43.        ... 
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;

class Person {
     public:
       string firstname() const;
       string lastname() const;
       ...
};

/*  仿函数,按名字排序
* - operator() returns whether a person is less than another person
*/
class PersonSortCriterion {
     public:
       bool operator() (const Person& p1, const Person& p2) const {
           /* a person is less than another person
            * - if the last name is less
            * - if the last name is equal and the first name is less
            */
           return p1.lastname()<p2.1astname() ||
                  (! (p2.1astname()<p1.lastname()) &&
                   p1.firstname()<p2.firstname());
       }
};

int main()
{
       //声名 set ,用这个仿函数
       typedef set<Person,PersonSortCriterion> PersonSet;

       //create such a collection
       PersonSet coll;
       ...

       //do something with the elements
       PersonSet::iterator pos;
       for (pos = coll.begin(); pos != coll.end();++pos) {
           ...
       }
       ...
}

三. 拥有内部状态的仿函数:

  1. #include <iostream> 
  2. #include <list> 
  3. #include <algorithm> 
  4. #include "print.hpp" 
  5. using namespace std; 
  6.  
  7. class IntSequence { 
  8.       private
  9.         int value; 
  10.       public
  11.         //constructor 
  12.          IntSequence (int initialValue) 
  13.           : value(initialValue) { 
  14.          } 
  15.  
  16.         //''function call'' 
  17.          int operator() () { 
  18.              return value++; 
  19.          } 
  20. };<span><span class="comment"></span></span> 
  21.  
  22. int main() 
  23.         list<int> coll; 
  24.  
  25.         //insert values from 1 to 9 
  26.         generate_n (back_inserter(coll),                  //start 
  27.                            9,                             //number of elements 
  28.                            IntSequence (1));              //generates values 
  29.  
  30.           PRINT_ELEMENTS(coll); //1 2 3 4 5 6 7 8 9 
  31.  
  32.           //replace second to last element but one with values starting at 42 
  33.           generate (++coll.begin(),                       //start 
  34.                     --coll.end(),                         //end 
  35.                     IntSequence (42));                    //generates values 
  36.  
  37.           PRINT_ELEMENTS(coll); //1 42 43 44 45 46 47 48 9 
#include <iostream>
#include <list>
#include <algorithm>
#include "print.hpp"
using namespace std;

class IntSequence {
      private:
        int value;
      public:
        //constructor
         IntSequence (int initialValue)
          : value(initialValue) {
         }

        //''function call''
         int operator() () {
             return value++;
         }
};

int main()
{
        list<int> coll;

        //insert values from 1 to 9
        generate_n (back_inserter(coll),                  //start
                           9,                             //number of elements
                           IntSequence (1));              //generates values

          PRINT_ELEMENTS(coll); //1 2 3 4 5 6 7 8 9

          //replace second to last element but one with values starting at 42
          generate (++coll.begin(),                       //start
                    --coll.end(),                         //end
                    IntSequence (42));                    //generates values

          PRINT_ELEMENTS(coll); //1 42 43 44 45 46 47 48 9
}

注:generate/generate_n 通过一个数值产生器类生成的数值来初始化一个容器, 通过将产生器函数gen返回的值赋给由迭代器指定的[first, last) or [first, first + n)范围内的所有元素, generate和generate_n算法初始化或重新初始化了一个序列。

引用方式传递仿函数

  1. generate_n<back_insert_iterator<list<int> >, int, IntSequence&>   
  2.            (back_inserter(coll),   //start   
  3.            4,      //number of elements   
  4.            seq);   //generates values   
generate_n<back_insert_iterator<list<int> >, int, IntSequence&>  
           (back_inserter(coll),   //start  
           4,      //number of elements  
           seq);   //generates values  
调用后,seq的值已经改变,下次再调用会用上次的值。

三. for_each()的返回值

for_each()可以返回其仿函数,这样你可以返回值获取仿函数的状态了。

for_each (InputIterator beg, InputIterator end, UnaryProc op ), 对区间[beg, end),中的每个elem调用op(elem)。

  1. MeanValue mv = for_each (coll.begin(), coll.end(), //range   
  2.                          MeanValue());             //operation   
  3. cout << "mean value: " << mv.value() << endl;  
MeanValue mv = for_each (coll.begin(), coll.end(), //range  
                         MeanValue());             //operation  
cout << "mean value: " << mv.value() << endl; 

四. 预定义的仿函数

#include <functional>

negate<type>()- param
plus<type>()param1 + param2
minus<type>()param 1 - param2
multiplies<type>()param1 * param2
divides<type>()param1 / param2
modulus <type>()param1 % param2
equal_to<type>()param1 == param2
not_equal_to<type>()param1 ! = param2
less<type>()param1 < param2
greater<type>()param1 > param2
less_equal<type>()param1 <= param2
greater_equal<type>()param1 >= param2
logical_not<type>()! param
logical_and<type>()param1 && param2
logical_or<type> ()param1 | | param2

  1. typedef set<int, greater<int> > IntSet;   
  2. typedef set<int, less<int> > IntSet;   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值