zoukankan      html  css  js  c++  java
  • c++ STL (五 适配器)

    1、基本概念

      适配器, 在STL中扮演着转换器的角色,本质上是一种设计模式,用于将一种接口转换成另一种接口,从而是原本不兼容的接口能够很好地一起运作。适配器不提供迭代器。

    2、基本类型

    根据目标接口的类型,适配器可分为以下几类:

      (1) 改变容器的接口,称为容器适配器;
      (2)改变迭代器的接口,称为迭代器适配器;
      (3)改变仿函数的接口,称为仿函数适配器。

    3、容器适配器

      容器的适配器有stack、queue、priority_queue,是在容器deque的基础进行了一些特定的约束,因而本质上并不属于容器,而是容器的适配器。

    4、迭代器适配器

      STL提供了很多应用于迭代器的适配器,主要有:有back_insert_iterator, front_insert_iterator, inser_iterator, reverse_iterator, istream_iterator, ostream_iterator, istreambuf_iterator, ostreambuf_iterator等等,下面介绍集中主要的迭代器适配器:
    (1)insert iterators

      这种迭代器,可以将迭代器的赋值操作转变为插入操作。根据功能的不同,还分为用于尾端插入的back_insert_iterator,用于头端插入的front_insert_iterator,用于任意位置插入的insert_iterator。示例如下:

     1 ostream_iterator<int> outline(cout," "); //输出迭代器的适配器
     2 
     3 int ia[] = {0,1,2,3,4,5}; 
     4 deque<int> id(ia,ia+6); 
     5 copy(id.begin(),id.end(),outline);//0 1 2 3 4 5 
     6 cout<<endl; 
     7 
     8 copy(ia+1,ia+2,front_inserter(id)); 
     9 copy(id.begin(),id.end(),outline);//1 0 1 2 3 4 5 
    10 cout<<endl;
    11  
    12 copy(ia+3,ia+4,back_inserter(id)); 
    13 copy(id.begin(),id.end(),outline);//1 0 1 2 3 4 5 3 
    14 cout<<endl; 
    15 
    16 deque<int>::iterator iter = find(id.begin(),id.end(),5); 
    17 copy(ia+0,ia+3,inserter(id,iter)); 
    18 copy(id.begin(),id.end(),outline);//1 0 1 2 3 4 0 1 2 5 3 
    19 cout<<endl;

    (2)reserve iterators

      这种迭代器,将一般迭代器的行进方向进行逆转,可以很好地应用于从容器尾端开始的算法。示例如下:

    1 copy(id.rbegin(),id.rend(),outline);//3 5 2 1 0 4 3 2 1 0 1
    2 cout<<endl;

    (3)iostream iterators

      这种迭代器,将自己绑定一个iostream对象身上,从而获得输入输出的功能。示例如下:

    1 ostream_iterator<int> outline(cout," "); 
    2 
    3 int ia[] = {0,1,2,3,4,5}; 
    4 deque<int> id(ia,ia+6); 
    5 
    6 copy(id.begin(),id.end(),outline);//0 1 2 3 4 5 
    7 cout<<endl;

    5、仿函数适配器

      仿函数适配器,相比于其他适配器更加地灵活,可以自由地组合适配。目前提供的适配操作包括以下这些:

      (1)联结(bind)。

      通过bind,我们仿函数与参数进行绑定,可实现算法所需的条件判断功能,例如判断小于12的元素时,可使用bind2nd(less(),12),就可以达到目的。

      (2)否定(negate)

      这里就是取反的操作,例如not1(bind2nd(less(),12)),就可判断不小于12的元素。

      (3)组合(compose)

      当算法的判断条件需要进行一些复杂的数学运算时,即可采用这种适配操作。例如对每个元素v进行(v+2)*3操作,就可表示为compose1(bind2nd(multiplies(),3),bind2nd(plus(),2))。

      (4)一般函数适配器

      一般函数可以当做仿函数供STL算法使用,但无配接能力,需要将其包装成仿函数,其原理就是在仿函数的运算符()内执行其所包装的函数即可。

      (5)成员函数适配器

      这里将成员函数包装成仿函数,从而可使用成员函数搭配各种泛型算法。当容器内存储的是对象的实体时,需使用mem_fun_ref进行适配;当容器内存储的是对象的指针时,需使用mem_fun进行适配。

      仿函数适配器的作用,就是将我们需要的东西包装成仿函数,已达到算法泛化的目的,测试示例如下:

     1 void print(int i) 
     2 { 
     3     cout<<i<<" "; 
     4 } 
     5 class Int 
     6 { 
     7 public: 
     8     explicit Int(int i):m_i(i) { } 
     9     ~Int() { } 
    10     void print1() 
    11     { 
    12         cout<<"["<<m_i<<"] "; 
    13     } 
    14     
    15 private: 
    16     int m_i; 
    17 }; 
    18 
    19 int ia2[] = {2,21,12,7,19,23}; 
    20 vector<int> iv(ia2,ia2+6); 
    21 cout<<count_if(iv.begin(),iv.end(),not1(bind2nd(less<int>(),12)));//4 
    22 cout<<endl; 
    23 
    24 for_each(iv.begin(),iv.end(),print);//2 21 12 7 19 23 
    25 cout<<endl; 
    26 
    27 for_each(iv.begin(),iv.end(),ptr_fun(print));//2 21 12 7 19 23 
    28 cout<<endl; 
    29 
    30 Int t1(3),t2(7),t3(20),t4(14),t5(68); 
    31 vector<Int> Iv; 
    32 Iv.push_back(t1); 
    33 Iv.push_back(t2); 
    34 Iv.push_back(t3); 
    35 Iv.push_back(t4); 
    36 Iv.push_back(t5); //当容器中存放的是对象实体的时候用mem_fun_ref 
    37 for_each(Iv.begin(),Iv.end(),mem_fun_ref(&Int::print1));//[3] [7] [20] [14] [68] 
    38 cout<<endl; 
    39 
    40 vector<Int*> Iv2; 
    41 Iv2.push_back(&t1); 
    42 Iv2.push_back(&t2); 
    43 Iv2.push_back(&t3); 
    44 Iv2.push_back(&t4); 
    45 Iv2.push_back(&t5); 
    46 
    47 //当容器中存放的是对象的指针的时候用mem_fun 
    48 for_each(Iv2.begin(),Iv2.end(),mem_fun(&Int::print1));//[3] [7] [20] [14] [68] 
    49 cout<<endl;
  • 相关阅读:
    poj 1860 Currency Exchange(最短路径的应用)
    poj 2965 The Pilots Brothers' refrigerator
    zoj 1827 the game of 31 (有限制的博弈论)
    poj 3295 Tautology (构造法)
    poj 1753 Flip Game(枚举)
    poj 2109 (贪心)
    poj 1328(贪心)
    Qt 对单个控件美化
    Qt 4基础
    Bash Shell
  • 原文地址:https://www.cnblogs.com/xietianjiao/p/12344319.html
Copyright © 2011-2022 走看看