博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Visual C++ 2008入门经典 第十章标准模板库
阅读量:6448 次
发布时间:2019-06-23

本文共 17343 字,大约阅读时间需要 57 分钟。

// 第十章标准模板库//.cpp : 定义控制台应用程序的入口点。//STL提供的功能//容器的定义以及如何创建和使用容器//迭代器的定义以及如休在容器中使用迭代器//STL可用的算法类型以及如何应用较常用的算法//函数对像的定义以及如何在STL中使用函数对像//如何使用支持C++/CLI类类型的STL版本//10.1 标准模板库的定义//STL包含六种组件: 容器, 容器适配器 迭代器 算法 函数对像和函数适配器//vector
strings;//vector
data;//STL容器类的模板在标准头文件中定义//
vector
容器表示一个在必要时可动增加容量的数组,只能在矢量容器的末尾添加新元素//
deque
容器实现一个又端队列,它等价于一个矢量,不过增加了向容器开头添加元素//
list
是一个双向链表//
是一个关链容器,用关联链(类型为K)存储确定链/对像对所有位置的第个对像(类型为T),映射中的第个键的值必须唯一一//这个头文件也定义multimap
容器,//基中键/对像对中的键不需要唯一//
set
容器是一个映射,基中名对像作为自身的键,集合中的所有对像必须唯一,使用对像作为自身的键的一个后果是无法在集合中修改对像,要修改对像,必须先删除它,然后插入修改后的版本//这个头文个也定在multimap
容器,它与集合容器相似,只是基中的条目不需要唯一//
定义表示固定位数的bitset
类模板,它通常用来存储表示一组状态或条件的标记(flag);//MVC++也包括定义hash_map
和hash_set
的头文件
,它们是map
和set
容器的非标准变体,因为它们是在stdext命名空间中定义的(而不是在std中),标准映射和集合容器用一个排序机制定位条目,而非标准hash_map和hash_set容器用巧用列机制定位条目//10.1.2 容器适配器//
默认情况下,queue
容器由deque
容器中的适配器定义,不过我们可以用list
容器定它,我们只能访问队列中第一个和最后一个元素,而且我们只能从后面添加元素,从前面删除元素,因此queue
容器的运行或多或少就像我们在咖啡店排队一样//这个头文件还定义了一个priority_queue
容器,它是一个排列它所包含的元素顺序的队列,因此最大的元素总是最前面,只有前端的元素可以被访问或删除,默认情况下,优化级队列由vector
中的适配器定义,不过我们可以用deque
作为基础容器//
默认情况下,堆栈容器用户deque
容器中的适配器定义,不过我们可以用vector
和list
容器定义它,堆栈是一种先进行出的容器//因此添加或删除元素总是发生在顶部,我们只能访问顶部元素//10.1.3 迭代器//迭代器的行为与指针相似,它对于访问除容器适配器定义的内容之外的所有STL容器的内容非常重要.容器适配器不支持迭代器//输入与输出迭代器://这些这些迭代器读写对像的序列,可能仅使用一次,为了读或写第二次,必须获得一个新的迭代器,我们可以在迭代器上进行下次运算//++iter或--iter//*iter//对于解引用运算,允许在输入迭代器的情况下进行只读访问,在输出迭代器的情况下进行只写访问//前向迭代器://前向迭代器结合了输入和输入迭代器的功能,因此我们可以对它们应用上面显示的运算,而且可以用他们进行访问和存储操作,//也可以重用向前迭代器向前的访向历一组对像,我们想foreach几次就foreach就几次//双向迭代器://双向迭代器提供了与前向迭代器相同的功能,此外,还允许的--iter和iter--运算,这意味们可以后向也可以前向foreach对像序列//随机访问迭代器://随机访问迭代器具有与双向迭代器相同的功能,不过还允许下列运算/*iter+n 或iter-niter+=n 或 iter-=niter1 - iter2iter1 < iter2 或 iter1 > iter2iter1 <= iter2 或 iter1 >= iter2iter[n]将一个迭代器递增或递减任意值n的能力允许随机访问对像的庥合,最后一个使用[]运算符的运算等价于*(iter+n)*///10.1.4 算法//算法是操作迭代器提供的一组对像的STL函数模板,因为对像是由迭代器提供的,所以算法不需要知道要处理的对像的来源//算法在两个标准头文件中定义:
头文件//10.1.5 函数对像//函数对像是重载()运算符的类类型的对像,即该类实现operator()()函数,函数对像类型在STL定义为模板,因此我们可以创建一个函数对像,其中overloaded()运算符函数使用我们的对像类型//很多算法使用函数对像来指定要进行的二元运算,或者指定谓词来确定要如何或是否进行特定的运算//谓语是一个返回bool类型的值的函数,因为函数对像是一种类型的对像,实现operator()()成员函数并返回bool类型的值,所以函数对像也是谓词//谓词有两个版本,分别是需要两个操作数的二无谓词和需要一个操作数的一无谓词,例如://小于或等于这样的比较以及AND和OR这样的逻辑运算作为二元谓词(它们是函数对像的成员)//逻辑运算NOT作为一元谓词(此谓词也是函数对像的成员)//函数对像模板在
头文件中定义,必要时我们也可以定义自己的函数对像,//1.01.6 函数适配器//函数适配器是允许合并函数对像以产生一个更复杂的函数对像的函数模板,//10.2 STL容器范围//10.3 序列容器//evctor
头文件:
创建一个表示存储T类型对像的动态数组类//list
头文件:
创建一个存储T类型的一个链表类//deque
头文件:
创建一个存储T类型对像的双端队列的类//10.3.1 创建矢量容器//vector
mydata;/*#include "stdafx.h"#include
#include
#include
using namespace std;int _tmain(int argc, _TCHAR* argv[]){ //创矢量容器最简单的方工 //vector
mydata; //push_back()函数向矢量的末尾添加一个新的元素 //mydata.push_back(1); //vector
mydouble(100); //创建一个包含有100个元素的矢量, 默认值为0 //将第二个元素赋值 //mydouble[2] = 2.00; //vector
mydata(100, -1); //将矢量中的元素初始化为不同的值 //如果在创建容器时不想创建元素,则可以通过调用它的reserve()函数来创建 //vector
mydata; //mydata.reserve(100); //reserve()函数的实参是要容红领巾的最小元素个数,如果实参小于矢量的当前容量,那么调用reserve()就没有用, //我们可以用外部数组中的元素作为初值来创建矢量图 //double data[] = {1.5, 2.5, 3.5, 4.5, 5.5, 6.5}; //vector
mydata(data, data+4); //data+4也就是长度,将四个元素插入其中 //vector
values
::iterator,基中T是矢量存储的对像类型 //vector
values
mydata(data, data+4); cout<
<<"the mydata is 容器的容量是:"<
<
::size_type; //保存容器的大小和容器的容量 vector
::size_type cap = mydata.capacity(); cout<<"cap::"<
<
::size_type类型,因为size_t.size_t是无符号整型,它也是sizeof运算符的结果以及new运算符返顺的值的类型 if(mydata.empty()){ cout<<"mydata empty"<
strings; cout<<"
values(5,66); //创建5个66数值的容器 values.resize(7,88); //重新设置为长度为7个,后面两个元素是88的数组 values.resize(10); //长度为10,后面两个添加上去的元素值为0 values.resize(4); //只保留前面4个的值,都是66 return 0;}*//*#include "stdafx.h"#include
#include
#include
using namespace std;template
void listInfo(vector
&v){ cout<<"Container capactity:"<
<
data; listInfo(data); cout<<"重新设置data的长度为100:"<
numbers(10, -1); cout<<"The initial values are:"; for(vector
::size_type i = 0; i
::iterator iter = numbers.begin(); iter
::size_type oldC = numbers.capacity(); //容量 vector
::size_type newC = oldC; listInfo(numbers); for(int i=0; i<1000; i++) { numbers.push_back(2*i); newC = numbers.capacity(); //新的容量 if(oldC < newC){ oldC = newC; listInfo(numbers); } }}*///10.3.3 访问矢量中的元素//for(vector
::size_type i=0; i
vec(5, 999);//vec.insert(vec.begin()+1, 88); //在当前第一个元素后面加88//vec.insert(vec.begin()+3, 3, 77);//insert()函数还有另一个在给定位置插入一个元素序列的版本,第一个实参是指向要插入第一个元素的位置的迭代器,第二个实参和第三个实参是指定要插入的某个来源中的元素范围的迭代器//vector
newvec(5,33);//newvec.insert(newvec.begin()+1, vec.begin()+1, vec.begin()+5);//erase()函数可以删除矢量中任何位置的一个或多个元素,但是它也是线性时间函数,通常会比较慢//newrec.erase(newvec.end()-2);//为了删除多个元素,需提供两个迭代器实参来指定间隔//newvec.erase(newvec.begin()+1, newvec.begin()+4);//正如前面所提到的,erase()和insert()操作比较慢,因此在使用矢量时要慎用它们,如果我们发现在应用程序中经常要用到它们,选择list
容器可能会更好//swap()函数用来交换两个矢量的内容,前提当然是假定这两个矢量中的元素的类型相同,//vector
first(5, 77);//vector
second(8, -1);//first.swap(second);//矢量的容量和内容交换了,大小当然也交换了//assign()函数用来用别一个序列替换一个矢量中的全部内容,下面是如何用别一个矢量中的序列替换一个矢量中的内容//vector
values;//for(int i=1; i<=50; i++)//{// values.push_back(2.5*i);//}//vector
new newdata(5,3.5);//newdata.assign(values.begin()+1, values.end()-1);//它用来删除newdata中的所有元素,然后插入values中除第一个和第二个元素外的所有元素的副本,//我们通过两个迭代器指定要插入的新序列,第一个迭代器指向要插入的第一个元素//第二个迭代器指向要插入的最后一个元素的下一个位置//newdata.assign(30, 99.5);//第一个实参是替换序列中的元素个数,//第二个实参是要使用的元素,这个语句将导致newdata的内容被删除并用30个元素替换,每个元素的值都是99.5//10.3.5 在矢量中存储类对像/*class T{public: T(); T(const T& t); ~T(); T& operator=(const T& t);}*//*class Person{public: Person(char* first="John", char* second = "Doe") { size_t length = strlen(first)+1; firstname = new char[length]; strcpy_s(firstname, length, first); length = strlen(second)+1; secondname = new char[length]; strcpy_s(secondname, length, second); } Person(const Person& p) { size_t length = strlen(p.firstname)+1; firstname = new char[length]; strcpy_s(firstname, length, p.firstname); length = strlen(p.secondname)+1; secondname = new char[length]; strcpy_s(secondname, length, p.secondname); } ~Person(){ delete[] firstname; delete[] secondname; } Person& operator=(const Person& p) { if(&p == this){ return *this; } delete[] firstname; delete[] secondname; size_t length = strlen(p.firstname)+1; firstname = new char[length]; strcpy_s(firstname, length, p.firstname); length = strlen(p.secondname)+1; secondname = new char[length]; strcpy_s(secondname, length, p.secondname); } bool operator<(const Person& p)const { int result = strcmp(secondname, p.secondname); //取得比较结果,等于返回0, 小于时返回小于0的值,大于返回大于0的值 //小于或者等于,并且姓也得小于 if(result < 0 || result == 0 && strcmp(firstname, p.firstname) < 0) return true; return false; } void ShowPerson() const { cout<
<<" "<
<
#include
#include "Person.h"using namespace std;//int _tmain(int argc, _TCHAR* argv[])int main(){ vector
people; const size_t maxLength = 5; char firstname[maxLength]; char secondname[maxLength]; while(true) { cout<<"请车入姓(按0退出):"; cin.getline(firstname, maxLength, '\n'); if(strlen(firstname) == 0){ break; } cout<<"请输入名:"; cin.getline(secondname, maxLength, '\n'); people.push_back(Person(firstname, secondname)); //cout<<"退出请输入0, 再录入请按1"; } cout<
::iterator iter = people.begin(); while(iter != people.end()){ iter++->ShowPerson(); } return 0;}*///10.3.6 排序矢量元素//在
头文件中定义的sort()函数模板会排序两个随机访问迭代器所指向的对像序列//这两个迭代器分别指向序列中的第一个对像和最后一个对像的下一个位置,//注意:随机访问迭代器至关重要,容量较小的迭代器会不够用,sort()函数模板用
<运算符来排列元素的顺序 因此我们可以用sort()模板来排序提供随机访问迭代器的任何容器的内容,只要它包含的对像可以用<运算符进行比较 sort(people.begin(), people.end()); *#include "stdafx.h"#include
#include
#include
#include
#include "Person.h"using namespace std;//int _tmain(int argc, _TCHAR* argv[])int main(){ vector
people; const size_t maxLength = 5; char firstname[maxLength]; char secondname[maxLength]; while(true) { cout<<"请车入姓(按0退出):"; cin.getline(firstname, maxLength, '\n'); if(strlen(firstname) == 0){ break; } cout<<"请输入名:"; cin.getline(secondname, maxLength, '\n'); people.push_back(Person(firstname, secondname)); //cout<<"退出请输入0, 再录入请按1"; } cout<
::iterator iter = people.begin(); while(iter != people.end()){ iter++->ShowPerson(); } sort(people.begin(), people.end()); cout<<"排序后开始循环输出"<
::iterator iter = people.begin(); vector
::iterator iter1 = people.begin(); while(iter1 != people.end()){ iter1++->ShowPerson(); } const size_t max = 100; int data[max]; int value = 0; size_t count = 0; for(size_t i = 0; i
>value; if(value == 0){ break; } data[count++] = value; } //开始使用sort排序 //sort (data, data+count); sort(data, data+count, greater
()); for(size_t i = 0; i
#include
#include
#include
#include "Person.h"using namespace std;//int _tmain(int argc, _TCHAR* argv[])int main(){ vector
people; //定义一个容器people,但元素为Person的指针 const size_t maxLength = 50; char firstname[maxLength]; char secondname[maxLength]; while(true){ cout<<"请车入姓(按0退出):"; cin.getline(firstname, maxLength, '\n'); if(strlen(firstname) == 0){ break; } cout<<"请输入名:"; cin.getline(secondname, maxLength, '\n'); //people.push_back(Person(firstname, secondname)); people.push_back(new Person(firstname, secondname)); //每个Person对像现在在堆上创建,地址传递给该矢量push_back()函数 //在容器中存储对像的地址要小心一些,如果在堆栈上创建对像,那么当函数退出时这些对像被销毁,存储的指针会变成无效指针 //如果用new运算符在堆上创建的对像,那么只有当用delete删除它们时对像才被销毁 } cout<
::iterator iter = people.begin(); while(iter != people.end()){ (*(iter++))->ShowPerson(); } //删除所有容器内容 iter = people.begin(); while(iter != people.end()){ delete *(iter++); } people.clear(); return 0;}*///10.3.8 双端队列容器//双端队列容器模板deque
是在
头文件中定义的,双端队列容器非常类似于矢量,//其功能与矢量容器相同,并且包括同样的函数成员,但是我们可以在序列的开头和结尾有效的添加和删除元素///deque
people;///向容器的前端添加元素的函数是push_front() pop_front删除第一个元素//people.push_front(Person(firstname, secondname));//deque
strings;//deque
items(50);//default value; //??什么意思//deque
values(5, 0.5);//deque
data(items.begin(), items.end());//与矢量相比它有一个缺点,由于它提供了额外的能力,双端队列的内存管理比矢量复杂//因此它会稍微慢一些//除非确实需要向容器的前端添加元素,否则矢量是更好的选择/*#include "stdafx.h"#include
#include
#include "Person.h"#include
#include
using namespace std;//int _tmain(int argc, _TCHAR* argv[])int main(){ deque
data; //定义双端队列 deque
::iterator iter; //存储一个迭代器,是一个指针 deque
::reverse_iterator riter; //存储一个反向迭代器 cout<<"请输入数值到队列中,0退出:"; int value = 0; while(cin>>value, value !=0){ data.push_front(value); //添加到头部 } cout<
中 //这个会累计前两个迭代器实参标识的元素序列的和,第三个实参指下和的一个初值 //并且其类武装必须与序列中的元素的类型相同,即使序列的和是空值,也要提供一个初值 //以确保我们总是得到有意义的结果,accumulate()函数返回运算结果, //我们可以对任何的数值类型的值序列应用accumulate()函数 return 0;}*///10.3.9 使用列表容器//在
头文件中定义的List
容器模板实现一个双向链表,与矢量或双端队列相比,列表容器最大的优点是可以在固定时间从序列的任意位置插入或删除元素//列表的容器的构造函数范围类似于矢量或双端队列//list
names;//list
< names(20); 长度为20//list
values(50, 2.17828);//list
samples(++values.begin(), --values.end());//与其他序列容器一样,我们可以调用列表的size()成员函数来查看它的无素数目前,也可以通过调用列表的resize()函数来修改它的元素数目//如果resize()的实参小于列表中的元素数目就从末尾删除元素,如果实参较大,就用存储的元素类型的默认构造函数添加元素//1 向列表中添加元素//提供了push_front() / push_back() / 还有第三个版本的insert()函数,//list
data(20, 1);//data.insert(++data.begin(), 77);//第一个实参是在插入位置指定的迭代器,第二个实参是要插入的元素,//在指定位置插入若干相同元素//list
::iterator iter = data.begin();//for(int i=0; i<9; i++){ //++iter;//}//data.insert(iter, 3, 88);//第一个实参是一个指定位置的迭代器//第二个实参是要插入的元素数目//第三个实参是要插入的元素//向列表中插入一个元素序列//vaector
numbers(10, 5); //生成一个序列//data.insert(--(--data.end()), numbers.begin(), numbers.end());//第一个实参是指向最后一元素之前的第二个元素迭代器//2 访问列表中的元素//通过调用列表front()或back()函数获得对列表中第一个或最后一个元素的引用//begin()/end(), rbegin()/rend()函数返回双向迭代器/*#include "stdafx.h"#include
#include
#include
using namespace std;int main(){ list
text; //列表容器 list
::iterator iter; //列表容器的迭代器 string sentence; while(getline(cin, sentence, '\n'), !sentence.empty()) text.push_front(sentence); cout<<"循环所有元素:"<
对像的sort()成员来排序内容,因为list
容器不提供随机访问迭代器 //所以不能使用在
头文件中定义的sort()函数,这就是list
模板定义它自己的sort()数成员的原因 for(iter = text.begin(); iter!= text.end(); iter++){ cout<<*iter<
numbers(data, data+8);//numbers.erase(++numbers.begin());//numbers.erase(++numbers.begin(), --(--numbers.end()));//remove()函数从列表中删除特定值的元素//numbers.remove(22);//assign()函数删除列表中的所有元素并将一个对象复制到列表中给定次数,或者复制品由两个迭代器指定一个对像序列//int data[] = {10,22, 4, 56, 89, 77, 13, 9};//list
numbers(data, data+8);//numbers.assign(10, 99); //后面添加两个99的元素//numbers.assign(data+1, data+4);//unique()函数将消除列表中相邻的重复元素,因此如果我们先排序内容,应用该函数可以确保所有元素都是碓一的//int data[] ={10, 22, 4, 10, 89, 22, 89, 10};//list
numbers(data, data+8);//numbers.sort(); //排序//numbers.unique();//splice()函数允许我们删除一个列表的全部或一部分,并将它插到中一个列表中//显然,两个列表必须存储相同类型的元素,下面是使用splice()函数的最简单方式//int data[] ={1, 2, 3, 4, 5, 6, 7, 8};//list
numbers(data, data+3); //三个元素 1 2 3 //list
values(data+4, data+8);//5 6 7 8 //numbers.splice(++numbers.begin(), values);//1 5 6 7 8 2 3 //splice()函数的第一个实参是一个迭代器,指定应在何处插入元素,//第二个实参是插入的元素来自的列表//这一操作删除values列表中的所有元素并立即将它们插入到numbers列表中的第二个元素前面//删除源列表中给定位置的元素,并将它们插入到目的地列表给定位置//int data[] = {1,2,3,4,5,6,7,8};//list
numbers(data, data+3); //1 2 3//list
values(data+4, data+8); //5 6 7 8//numbres.splice(numbers.begin(), vlaues, --values.end()); //8 1 2 3 //splice()函数的前两个实参与该函数上一个版本相同//第三个实参是一个迭代器,指定要从源列表中选择的第一个元素的位置,这个位置到末尾的所有元素都被从源列表中删除,并插入目的列表中//splice()的第三个版本需要四个实参,并从源列表中选择一个元素范围//int data[] = {1, 2, 3, 4, 5, 6, 7, 8};//list
numbers(data, data+3);//list
values(data+4, data+8);//numbres.splice(++numbres.begin(), values, ++values.begin(), --values.end());//merge()函数删除我们作为一个实参提供列表中的元素,并将它们插入调用该函数的列表中,//然后函数默认会按升序方式排序扩展列表的内容,//int data[] = {1, 2, 3, 4, 5, 6, 7, 8};//list
numbres(data, data+3); //1 2 3//list
values(data+1, data+8);//2 3 4 5 6 7 8//numbres.merge(values);//这段代码将values的内容合并到numbres中,因此执行此操作后values将变空,接受一个实参的merge()函数默认情况下以升序方式排列结果的顺序//因为两个列表的值都已经排序//numbers.sort(greater
());//numbers.sort(greator
());//numbers.merge(values, greater
());//这里我们用在
头文件中定义的,greater
()函数对像来指定应以降序方式排序的列表,它们将在相同的序列中合并//remove_if()函数基于应用一元谓词的结果来删除列表中的元素,/*#include "stdafx.h"#include
#include
#include
using namespace std;template
class is_negative: public std::unary_function
{public: result_type operator() (T& value){ return value < 0; }};//template
class is_negative_//{//public:// bool operator() (T& value){// return value < 0;// }//};//这里我们不需要
的#include 指令,因为没有使用基础模板,这样比罗简单//可能也更容易理解,不过在此包含原始版本只是为了显示如何使用基础模板,如果打算在更通用的上下文中使用谓词//特别是如果要在函数适配器中使用它,则可能想这么想template
void listlist(list
& data){ for(list
::iterator iter = data.begin(); iter != data.end(); iter++){ cout<<*iter<<" "; } cout<
void loadlist(list
& data){ T value = 0; while(cin>>value, value != 0){ data.push_back(value); }}int main(){ list
numbers; cout<<"现在开始输入内容:"<
()); cout<<"After applying the remove_if() function the list contains:"<
values; loadlist(values); cout<<"The list contains:"<
()); cout<<"After applying the remove_if() function() the list contains."<
morevalues; loadlist(morevalues); cout<<"显示的moreValues:"<
()); cout<<"显示的列表:"<
()); morevalues.sort(greater
()); values.merge(morevalues, greater
()); cout<<"合并values和morevalues以后:"<
); //numbers.sort(greater
); return 0;}//输出显示了用于int类型和double类型的值的谓词,remove_if()函数依次向列表中的各个元素应用谓词,并删除谓词返回true的元素*///10.3.10 使用其他序列容器//1 队列容器//queue
容器通过适配器实现先进先出存储机制,我们只能向队列的末尾添加或从开头删除元素//queue
names;//queue
> names;//适配器模板的第二个类型形参指定要使用的低层序列容器,队列甜酸器类扮演低层容器类的包装器的角色,//back() 返回对列后端的元素的引用,这个函数有两个版本,一个版本返回const 引用户// 另一个版本返回非const引用,如果队列为空,则返回的值不确定//front() 返回对队列前端的元素的引用,这个函数有两个版本,一个版本返回const引用,另一个非const引用//push() 将实参指定为元素添加的到队列的后端//pop() 删除队列前端的元素//size() 返回队列中的元素数目//empty() 如果队列为空则返回true,否则返回false/*#include "stdafx.h"#include
#include
#include
using namespace std;int main(){ queue
sayings; string saying; cout<<"添加字符串:"<
容器是一个队列,它的顶部总是具有最大或最高优先级,//priority_queue
numbers;//当向队列中添加元素时确定元素的相对优先级的默认条件是标准less
函数对像模板//我们用push()函数向优先级队列中添加一个元素//numbres.push(99);//top() 返回对优先级队列前端元素的const引用,它将是容器中最大或最高优先级的元素,如果优先级队列为空,则返回的值不确定//push() 将实参指定的元素添加到优先级队列中由容器的谓词确定的位置,默认为less
//pop() 删除优先级队列前端的元素,它将是容器中最大或优先级最高的元素//size() 返回优先级队列中的元素数目//empty() 如果优先级队列为空则返回true,否则返回false//注意: 优先级除列与队列容器的可用函数之间有一个明显的区别,使用优先级队列时不能访问队列后端的元素,只能访问前端的元素//默认情况下,优先级队列适配类使用的基础容器为vector
,我们可以选择指定不同的序列容器作为基础,并选择一个备用函数对像来确定元素的优先级//priority_queue
, greater
> numbers;//三个模板形参是元素类型 / 要用作基础的容器,要用来排列元素顺序的谓词类型/*#include "stdafx.h"#include
#include
#include
#include
#include
using namespace std;class Person{public: Person(string first, string second) { firstname = first; secondname = second; } Person(){}; Person(const Person& n){ firstname = n.firstname; secondname = n.secondname; } bool operator<(const Person& p)const{ if(secondname < p.secondname || ((secondname == p.secondname) && (firstname < p.firstname)) ){ return true; } return false; } bool operator> (const Person& n)const { return n < *this; } //重载的>运算可以防止用greater
谓词类型排列Person对像的顺序 void showPerson() const { cout<
<<" "<
<
{public: result_type operator()(const first_argument_type& p1, const second_argument_type& p2) const { return p1 > p2; }private:};int main(){ //定义一个优先级的队列容器 priority_queue
, greater
> people; //不要将模板实例中使用的类型实参greater
与可能作为sort()算法的实参的对像greater
()相混淆 string first, second; while(true){ cout<<"请输入姓:"<
容器适配器模板在
头文件中定义,默认情况下基于deque
容器实现向下推栈,向下推栈是一种后进先出机制,只能访问最近添加到堆栈的对像//stack
people;//基础容器可以是支持back() push_back()和pop_back()操作的任何序列容器,//stack
> names;//top() 返回对堆栈顶部元素的引用,如果堆栈为空,则返顺的值不确定,我们可以将返回的引用赋给一个const或非const引用,如果赋予后者,就可以在堆栈中修改对像//push() 向堆栈顶部添加实参指定的元素//pop() 删除堆栈的元素//size() 返回堆栈中的元素数目//empty() 如果堆栈为空则返回true, 否则返回false/*#include "stdafx.h"#include
#include
#include
#include
using namespace std;class Person{public: Person(string first, string second) { firstname = first; secondname = second; } Person(){}; Person(const Person& n){ firstname = n.firstname; secondname = n.secondname; } bool operator<(const Person& p)const{ if(secondname < p.secondname || ((secondname == p.secondname) && (firstname < p.firstname)) ){ return true; } return false; } bool operator> (const Person& n)const { return n < *this; } //重载的>运算可以防止用greater
谓词类型排列Person对像的顺序 void showPerson() const { cout<
<<" "<
<
> people; string first, second; while(true){ cout<<"请输入姓:"<

  

转载地址:http://uoowo.baihongyu.com/

你可能感兴趣的文章
通过DataWorks数据集成归档日志服务数据至MaxCompute进行离线分析
查看>>
阿里云积极落实等级保护制度,政务云全国首个通过等保2.0合规评测
查看>>
本地Git与远程Gitblit 服务器相关操作
查看>>
学习Python编程的最好的几本书
查看>>
仿抖音底部导航效果(二)
查看>>
再看JVM:垃圾回收那些事
查看>>
【翻译】CodeMix使用的语言和框架(三):Python
查看>>
【Infragistics教程】使用可重复使用的自定义组件更快地创建原型
查看>>
4.31-35nginx相关的一些补充
查看>>
Java 中的异常和处理详解
查看>>
不是技术牛人,如何拿到国内IT巨头的Offer
查看>>
centos7安装mysql
查看>>
Xmind教程之五种主题
查看>>
cs224d 课程学习第一课
查看>>
Linux 挂载光盘:mount: you must specify the filesystem
查看>>
OSChina 周三乱弹 —— 写代码强迫症
查看>>
OSChina 儿童节乱弹 —— 六一不能让童工加班!
查看>>
linux command
查看>>
新魔方玩法
查看>>
golang标准包中文版
查看>>