body, table{font-family: 微软雅黑; font-size: 10pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

适配器:
  适配器相当于提供了一个接口,使得某些不适用于特定对象的方法可以被该对象所用,适配器形象的功能图解如所示,图中,容器或函数对象无法直接应用于算法,因此,必须有一种中间过渡机制来实现两者的匹配,这就是适配器,本质上,适配器是使一事物的行为类似于另一事物的行为的一种机制。
容器适配器:
1、容器适配器可以看作是对容器的封装,使其具有某些特殊的功能。容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现,只是发生了接口转换而已。标准库提供了三种序列容器适配器:        
                stack(deque,list)、
                queue(deque,list)、        
                priority_queue(vector, deque)。
2、所有适配器都定义了两个构造函数:默认构造函数用于创建空对象,而带一个容器参数的构造函数将参数容器的副本作为其基础值。
3、默认的stack和queue都基于deque容器实现,而priority_queue则在vector容器上实现。在创建适配器时,通过将一个顺序容器指定为适配器的第二个类型参数,可覆盖其关联的基础容器类型。例如,下述代码创建的ob栈是基于vector实现的:stack<int, vector<int> > ob;
#include<iostream>
#include<vector>
#include<stack>
#include<string>
using namespace std;
int main()
{
        stack<int,vector<int> > ob1; //使用vector取代其默认的deque做为stack的实现基础
        cout<<ob1.size()<<endl;
        for(int i=0;i!=10;++i)
        {
                ob1.push(i);
        }
        cout<<ob1.size()<<endl;
        cout<<ob1.top()<<endl;
        ob1.pop();
        cout<<ob1.top()<<endl;
        cout<<"********"<<endl;

        stack<string,vector<string> > ob2;
        for(char i=65;i!=91;++i)
        {
                string tmp = string(1,i);
                ob2.push(tmp);
        }
        cout<<ob2.top()<<endl;
        ob2.pop();
        cout<<ob2.top()<<endl;
        return 0;
}

#include <iostream>
#include <queue>
using namespace std;
int main()
{
        queue<int> queInt;
        for(int idx = 0;idx < 10; ++idx)
        {
                queInt.push(idx);     //入队
                cout<< queInt.back() <<" 入队"<<endl;     //取队尾元素
        }
        cout<<queInt.size()<<" 个元素已经入队"<<endl;
        while(!queInt.empty())
        {
                cout<< queInt.front() <<" 出队"<<endl;    //取队头元素
                queInt.pop();    //出队
        }
        cout<< queInt.size()<<endl;
        return 0;
}
#include <iostream>
#include <queue>
using namespace std;
//采用的是"堆排序"进行元素的调整,默认情况下,比较函数是"<" 符号,堆顶的元素要与新进来的元素进行比较,如果为true,则将堆顶的元素放到堆底,新进来的元素放到堆顶;然后进行堆的调整

//出队从大到小
int main()
{
        int arr[10]={0,1,3,2,5,6,9,8,7,4};
        priority_queue<int> pqueInt;
        for(int idx = 0;idx != 10; ++idx)
        {
                pqueInt.push(arr[idx]);
                cout<< pqueInt.top() <<"是优先级别最高的"<<endl;
        }
        while(!pqueInt.empty())
        {
                cout<< pqueInt.top() <<"出队"<<endl;
                pqueInt.pop();
        }
        return 0;
}


迭代器适配器:
1、流迭代器也是迭代器适配器,此外,还包括反向迭代器和插入迭代器。和使用流迭代器一样,使用反向和插入迭代器都必须包含头文件 #include<iterator>。
(1)反向迭代器
(2)插入迭代器适配器
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
        vector<int> vecInt = {1,2,3,4,5};
        vector<int>::iterator it=vecInt.begin();
        for(auto &elem:vecInt)
                cout<<elem<<" ";
        cout<<endl<<"-----------------------------------------"<<endl;

        ostream_iterator<int> osi (cout," ");    //创建输出流迭代器
        vector<int>::reverse_iterator rit = vecInt.rbegin();    //创建反向迭代器
        copy(rit,vecInt.rend(),osi);     //输出,容器中的内容拷贝到输出流迭代器中
//rit直接换成vecInt.rbegin()也可以
        cout<<endl;
        return 0;
}

#include <iostream>
#include <iterator>
#include <vector>
#include <list>
using namespace std;
template <typename Container>
void printElements(Container c)
{
        typename Container :: iterator it;
        for(it = c.begin();it != c.end(); ++it)
        {
                cout<<*it<<" ";
        }
        cout<<endl;
}
int main()
{
        vector<int> vecSrc = {1,2,3};
        list<int> listDest;
        copy(vecSrc.begin(),vecSrc.end(),back_insert_iterator<list<int> >(listDest));  
//尾插法,把vecSrc中的内容插入到listDest
        printElements(listDest);
        cout<<"--------------------------------"<<endl;
        list<int> listDest1;
        copy(vecSrc.begin(),vecSrc.end(),front_insert_iterator<list<int> >(listDest1));  
//头插法,把vecSrc中的内容插入到listDest1
        printElements(listDest1);
        cout<<"--------------------------------"<<endl;
        copy(vecSrc.begin(),vecSrc.end(),insert_iterator<list<int> >(listDest,++listDest.begin())); 
//指定位置插入法,把vecSrc中的内容,从listDest2的第二个位置开始插入
        printElements(listDest);
        return 0;
}


函数适配器:
函数适配器共有如下3种:
#include <functional>
1. 绑定器,有两个:
bind1st  (函数对象,指定值);    (过时)
将指定值绑定到函数对象的第1个参数上。
bind2nd  (函数对象,指定值);   (过时)
将指定值绑定到函数对象的第2个参数上。
bind  (函数对象,指定值… C++11)
绑定的参数的个数不受限制;对于不事先绑定的参数,需要传std::placeholders进去,从 _1 开始,依次递增(占位符)
2. 否定器,也有两个:
——not1()         //用于逆转一元断言
——not2()         //用于逆转二元断言
3. 成员函数适配器,也是两个:
——mem_fun()             //容器参数为类指针
——mem_fun_ref()        //容器参数为类对象
——mem_fn()       两者都能用(C++11)
绑定的参数的个数不受限制;对于不事先绑定的参数,需要传std::placeholders进去,从_1开始,依次递增

#include <iostream>
#include <functional>
using namespace std;
int func(int x,int y)
{
        return x+y;
}
class A
{
        public:
        A()
        {
                cout<<"A()"<<endl;
        }
        A(const A & rhs)
        {
                cout<<"A(const A&)"<<endl;
        }
        int func(int x,int y)
        {
                cout<<"A::func(int,int)"<<endl;
                cout<<"x="<<x<<endl;
                cout<<"y="<<y<<endl;
                return x+y;
        }
};
int main()
{
        auto f1=bind(func,10,placeholders::_1); 
 //绑定函数func,第一个参数为10,另外一个参数先不绑定,使用占位符
        cout<<f1(20)<<endl;     //占位符所在参数为20
        A a;
        auto f2=bind(&A::func,&a,placeholders::_1,placeholders::_2);
//这里A::func必须取地址,不然报错:这不是一个静态成员
//&a 和 a 的区别,一个不调拷贝构造函数,一个调构造函数
       // auto f2=bind(&A::func,placeholders::_1,placeholders::_2,placeholders::_3);
       // cout<<f2(a,1,2)<<endl;
        cout<<f2(1,2)<<endl;
        return 0;
}

#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
void f(int n1,int n2,int n3,const int & n4,int & n5)
{
        cout<<"("<<n1<<","<<n2<<","<<n3<<","<<n4<<","<<n5<<")"<<endl;
}
struct Foo
{
        int data=10;    //C++11新特性
};
int main()
{
        int n=7,m=8;
        auto f1=bind(f,_2,_1,42,cref(n),ref(m));    //占位符数字表示第几个参数
        n=10;
        f1(1,2,1001,1002,1003);  
//2,1,42,10,8   实参调用时可以传递多余的参数,但是无效
        Foo foo;
        foo.data = 12;
        auto f3 = bind(&Foo::data,_1);     //还可以绑定数据成员
        cout<<f3(foo)<<endl;
        // auto f4 = bind(&Foo::data,foo);
        // cout<<f4(foo)<<endl;
        return 0;
}

#include<iostream>
#include<functional>
using namespace std;
using namespace std::placeholders;
struct foo
{
        void sum(int x,int y) {  cout<<x+y<<endl;  }
        int data = 10;
};
int main()
{
        foo fo;
        auto f1 = bind(&foo::sum,fo,_1,_2);
        f1(1,2);
        fo.data = 12;
        auto f2 = bind(&foo::data,&fo);  // &fo,不要写fo,这样效率不高
        cout<<f2(10)<<endl;  // 12
        auto f3 = bind(&foo::data,_1);   // 编译通过,但是不知道怎么用  f3(fo);
}
//3
//12

//函数适配器
//否定器,not1() 用于逆转一元断言
//not2() 用于逆转二元断言
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
template<typename Container>
void print(Container& v)
{
        for(auto& elem:v)
                cout<<elem<<"  ";
        cout<<endl;
}
int main()
{
        int arr[] = {1,2,3,4,5,6,7};
        vector<int> v1(arr,arr+sizeof(arr)/sizeof(int));
        print(v1);
        less<vector<int>::value_type> it;
        vector<int> tmp(v1);
        replace_if(tmp.begin(),tmp.end(),bind1st(it,3),7);  // it为小于3,最终就是大于3的数据改成7
        print(tmp);
        tmp.clear();
        tmp = v1;
        replace_if(tmp.begin(),tmp.end(),not1(bind1st(it,3)),7);  // 否定器,小于3的改成7
        print(tmp);
        tmp.clear();
        tmp = v1;
        replace_if(tmp.begin(),tmp.end(),bind1st(not2(it),3),7);  // it被否定成大于3,所以最终就是小于3的数据被换成7
        print(tmp);
}
//成员函数适配器
#include<iostream>
#include<functional>
using namespace std;
using namespace std::placeholders;
struct foo
{
        void display_greeting(){  cout<<"hello,world!"<<endl;  }
        void display_num(int n){  cout<<n<<endl;  }
        int data = 7;
};
int main()
{
        foo fo;
        auto f1 = mem_fn(&foo::display_greeting);  // _1这个占位符可要可不要
        f1(fo);
        auto f2 = mem_fn(&foo::display_num);
        f2(fo,6);
        auto f3 = mem_fn(&foo::data);
        cout<<f3(fo)<<endl;
        return 0;
}

//成员函数适配器
//mem_fun()  //函数参数为类指针
#include<iostream>
#include<functional>
#include<algorithm>
#include<vector>
using namespace std;
class Num
{
        int _val;
        public:
        Num(){ _val=0; }
        Num(int val){ _val=val; }
        bool display(){ cout<<_val<<"  "; return true; }
        int squareval(){ _val*=_val; return _val; }
        int lessconst(int k){ _val-=k;return _val; }
        friend ostream& operator<<(ostream& os,const Num& rhs);
};
ostream& operator<<(ostream& os,const Num& rhs)
{
        os<<rhs._val;
}
int main()
{
        vector<Num*> v1;
        Num arr[10];
        for(int i=0;i<10;++i)
        {
                arr[i] = Num(i+1);
                v1.push_back(&arr[i]);
        }
        cout<<"原始数据:"<<endl;
        for_each(v1.begin(),v1.end(),mem_fun(&Num::display));
        //for_each(v1.begin(),v1.end(),mem_fun<bool,Num>(&Num::display));
// 两种写法都可以啊
        cout<<endl;
        // for_each(v1.begin(),v1.end(),mem_fun(&Num::squareval));
        for_each(v1.begin(),v1.end(),mem_fun<int,Num>(&Num::squareval));
        cout<<"数据平方:"<<endl;
        for(auto& elem:v1)
        cout<<*elem<<"  ";
        cout<<endl;
        for_each(v1.begin(),v1.end(),bind2nd(mem_fun<int,Num>(&Num::lessconst),5));
// bind2nd(函数对象,指定值) 把指定值绑定到函数对象的第二个参数上
        cout<<"减去常数:"<<endl;
        for(auto& elem:v1)
        cout<<*elem<<"  ";
        cout<<endl;
        return 0;
}
//成员函数适配器
//mem_fun_ref()   // 函数参数为类对象
#include<iostream>
#include<functional>
#include<algorithm>
#include<vector>
using namespace std;
class Num
{
        public:
                Num(){  val = 0;  }
                Num(int _val){  val = _val;  }
                bool display(){  cout<<val<<"  "; return true;  }
                bool isEven(){  return (bool)(val%2);  }
                bool isPrime()
                {
                        for(int i=2;i<(val/2);++i)
                                if(!(val%i)) return false;
                        return true;
                }
                friend ostream& operator<<(ostream& os,const Num& rhs);
        private:
                int val;
};
ostream& operator<<(ostream& os,const Num& rhs)
{
        os<<rhs.val;
}
int main()
{
        vector<Num> v1(12);  // 开辟12个空间
        //容器参数为类对象,Num
        for(int i=0;i<12;++i)
        {
                v1[i] = Num(i+1);
        }
        vector<Num>::iterator it;
        cout<<"原始数据:"<<endl;
        // for_each(v1.begin(),v1.end(),mem_fun_ref(&Num::display));
        for_each(v1.begin(),v1.end(),mem_fun_ref<bool,Num>(&Num::display));  // 这样写也可以
        cout<<endl;
        cout<<"删除质数:"<<endl;
        it = remove_if(v1.begin(),v1.end(),mem_fun_ref(&Num::isPrime));
        for(auto& elem:v1)
                cout<<elem<<"  ";
        cout<<endl;
        v1.erase(it,v1.end());
        for(auto& elem:v1)
                cout<<elem<<"  ";
        cout<<endl;
        vector<Num> v2(12);
        for(int i=0;i<12;++i)
        {
                v2[i] = Num(i+1);
        }
        v2.erase(remove_if(v2.begin(),v2.end(),mem_fun_ref(&Num::isEven)),v2.end());
        cout<<"删除基数:"<<endl;
        for(auto& elem:v2)
                cout<<elem<<"  ";
        cout<<endl;
        return 0;
}

适配器 STL的更多相关文章

  1. C++的STL

    今天,看一段代码的时候发现只一句话就做了个排序,是这样的: sort(rotateArray.begin(),rotateArray.end()); 很震惊,后来查了一下sort的用法, sort函数 ...

  2. STL学习系列七:优先级队列priority_queue容器

    1.简介 最大值优先级队列.最小值优先级队列 优先级队列适配器 STL priority_queue 用来开发一些特殊的应用,请对stl的类库,多做扩展性学习 这里给个例子: #include< ...

  3. c++ (P262—P277) STL

    STL的六大组件 容器(Container),是一种数据结构,如list,vector,和deques ,以模板类的方法提供.为了访问容器中的数据,可以使用由容器类输出的迭代器: 迭代器(Iterat ...

  4. STL总结之queue, priority_queue, stack

    之所以把这三个容器放在一起,是因为他们都是容器适配器.   STL中queue就是我们常用的FIFO队列,实现是一个容器适配器,这种数据结构在网络中经常使用.   queue的模板声明: templa ...

  5. C++ STL 一般总结

    以下内容来源网上 经过整合而成(转载) 一.一般介绍 STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库.它被容纳于C++标准程序库( ...

  6. C++顺序性容器、关联性容器与容器适配器

    什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象 ...

  7. STL之优先级队列priority_queue

    摘要: priority_queue,自适应容器(即容器适配器):不能由list来组建: 最大值优先级队列(最大值始终在对首,push进去时候) 最小值优先级队列: 优先级队列适配器 STL  pri ...

  8. STL之Queue(Q)

    STL的Queue(数据结构中的队列): 特点:FIFO 先进先出: 自适应容器(即容器适配器)   栈适配器STL queue  STL中实现的Queue: 用list来实现queue: queue ...

  9. C++之STL总结精华笔记

                       一.一般介绍      STL(StandardTemplate Library),即标准模板库,是一个具有工业强度的,高效的C++程序库.它被容纳于C++标准程 ...

随机推荐

  1. Idea的注入和自动编译配置

    实时编译: 第二个(防止编译时Autowired报错): 修改成:

  2. mysql 约束条件 外键 forigen key 介绍

    外键 forigen key作用 :建立表之间的关系 什么是外键 员工信息表有这些字段:id号  姓名 性别 员工所在部门名 部门描述信息 公司有3个部门,但是有1个亿的员工,那意味着 员工所对应的部 ...

  3. IOS 自己定义UITableView

    依据不同须要,须要使用tableview的结构,可是里面每个cell,又须要自己的样式.所以学习了一下如何把自定义的cell加到tableview里面 首先要自己创建一个类,继承UITableView ...

  4. PhotoSwipe中文API(四)

    在幻灯片自定义HTML内容 为了使PhotoSwipe显示HTML内容的幻灯片,你需要在幻灯片对象定义html属性.它应该包含HTML字符串或DOM元素对象. var items = [ // sli ...

  5. WordPress配置

    1.准备工作: 下载comsenzexp.exe 下载wordpress.zip 2.安装comsenzexp.exe,安装有个wwwroot目录: 3.解压wordpress.zip,然后ctrl+ ...

  6. Java实现最基本的集中排序

    排序是一个很重要的概念,现实生活中,我们需要为很多的东西排序.下面我们就介绍几种简单的排序的方法和最基本的思想. 1.冒泡排序:假设一个数组中有10个数字,从左边开始

  7. SpringMVC—概述

    mvc容器的实例化: http://blog.csdn.net/lin_shi_cheng/article/details/50686876 Spring的启动过程: 1: 对于一个web应用,其部署 ...

  8. sqlserver create table

    ①sql 语句创建(项目使用) use sps_db go if exists(select name from sys.tables where name='event_profile_level2 ...

  9. Qt多线程同步总结

    1.QMutex   QMutex mutex;   void func() { mutex.lock(); ........ mutex.unlock(); }   2.QMutex联手QMutex ...

  10. 项目管理工具- Maven

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3. ...