//10.4 关联容器//关联容器(如map )最重要的特性是无需搜索就可检索特定对像,关联容器内容T类型对像的位置由与对像一起提供的类型为K的键确定,因此只要提供适当的键就可以快速地检索任何对像,该键实际上是一个确定映射中的条目顺序的排序键//对于set 和nultiset 容器,对像作为它们自己的键,//10.4.1 使用映射容器//映射容器的模板在家
input(cin), input_end; //创建两个输入流迭代器,用来从标准输入流input和input_end中读取int类型的值 ostream_iterator
out(cout, " "); //创建一个输入流迭代器,将int类型的值传输给标准输出流,跟在每个输出值后面的分隔符是一个空格 copy(input, input_end, back_inserter
>(numbres)); //我们通过两个输入流迭代器input和input_end指定复制操作的数据源,复制操作的目的地是numbres容器的后端插入迭代器 //因此,复制操作会通过后端插入迭代器将cin中的数据值传输到numbres容器中 cout<<"输入的数据如下:"< 头文件定义了一个可扩展的模板集合,用来创建可用于算法和容器的函数对像,//less 创建一个二元谓词,表示T类型之间的 <运算,例如:less> ()定义一个比较string类型对像的函数对像//less_equal 创建一个二元谓词,表示T类型对像之间的<=运算,例如:less_equal ()定义一个比较double类型对像的函数对像//equal 创建一个二元谓词,表示T类型对像之间的==运算//not_equal 创建一个二元谓词,表示T类型对像之间的!=运算//geater_equal 创建一个二元谓词,表示T类型对像之间的>=运算//greater 创建一个二元谓词,表示T类型对像之间的>运算//not2 创建一个二元谓词,它是B类型的二元谓词的负值,例如,not2(less )创建一个二元谓词来比较int类型的对像//如果左操作数不小于右操作数,则返回true//下面的代码是用not2 模板来定义用于sort()算法的二元谓词//sort(v.begin(), v.end(), not2(greater ()));// 头文件还定义对元素进行算术运算的函数对像//plus 计算两个T类型元素的和//minus 通过从第一个操作数中减去第二个操作数计算两个T类型元素之间的差//multiplies 计算两个T类型元素的积//divides 用第一个T类型操作数除以第二个T类型操作数//modulus 计算第一个T类型操作数除以第二个操作数后的余数//negate 返回它的T类型操作数的负值//10.7 关于算法的更多内容// 头文件中的这些算法主要用来处理数组中的数值,// 头文件中的算法大多用搜索,排序和合并迭代器指定的对像序列//10.7.1 fill()//fill(ForwardIterator begin, ForwardIterator end, const Type& value);//它会用值填充由迭代器begin()和end()指定的元素//fill(v.begin(), v.begin()+9, "invalid");//10.7.2 replace()//replace(ForwardIterator begin, ForwardIterator end, const Type& oldValue, const Type& newValue);//函分析begin()和end()指定的每个元素,并用newValue替换出现的每个oldValue//replace(v.begin(), v.end(), "yes", "no");//replace()函数也会使用指针//char str[] = "A nod is as good as a wink to a blind hors.";//replace(str, str+strlen(str), 'o', '*');//10.7.3 find();//find(InputIterator begin, InputIterator end, const Type& value);//搜索由首次出现在value的前两个实参指定的序列//vector ::itertor iter = find(v.begin(), v.end(), 21)//find()算法反复查找出现的所有给定值//vector #include #include #include #include using namespace std;int _tmain(int argc, _TCHAR* argv[]){ ouble values[] = {2.5, -3.5, 4.5, -5.5, 6.5, -7.5}; vector data(values, values+6); transform(data.begin(), data.end(), data.begin(), negate ()); vector ::iterator iter = data.begin(); int i = 0; while(iter != data.end()) { i++; //cout<<"i="< < #include #include #include #include using namespace std;int _tmain(int argc, _TCHAR* argv[]){ double values[] = {2.5, -3.5, 4.5, -5.5, 6.5, -7.5}; vector data(values, values+6); vector squares(data.size()); transform(data.begin(), data.end(), data.begin(), squares.begin(), multiplies ()); ostream_iterator out(cout, " "); copy(squares.begin(), squares.end(), out); system("pause"); return 0;}*///10.8 C++/CLI程序中的STL//STL/CLR包含在cliext命名空内,因此所有STL名称都用cliext而不是std限定//10.8.1 STL/CLR容器/*T (const T% t){}//构造函数T% operator=(const T% t){}//重载=运算符~T(){ }//析构函数*///这些容器操作也要求定义无实参构造函数和operator==function,当容器存储对像而不是句柄时,如果需要为容器中的元素分配空格,就可以要用到无实参构造函数,如果在一个关联容器(如集合或映射)中存储引用类型的句柄或者值类型,它们至少必须重载一个运算符--默认要求重载operator<()//10.8.2 使用序列容器//本地C++的STL提供的所有序列容器也可用于STL/CLR,STL/CLR实现本地STL容器支持的所有操作,只是使用C++/CLI类型时可能会出现一些区别,下面通过一些示例来介绍这些区别/*ref class Person{public: Person():firstname(""), secondname(""){} Person(String^ first, String^ second):firstname(first), secondname(second){} virtual String^ ToString() override { return firstname+L" "+secondname; }private: String^ firstname; String^ secondname;};*///我们只在矢量中存储Person对像的句柄,因此不需要实现复制构造函数或赋值运算符,//ToString()函数重写了继承自类Object的版本,并且出于输出的目的/*#include "stdafx.h"#include #include //using namespace System;using namespace cliext;ref class Person{public: Person():firstname(""), secondname(""){} Person(string^ first, string^ second):firstname(first), secondname(second){} virtual String^ ToString() override { return firstname+L" "+secondname; }private: string^ firstname; string^ secondname;};int _tmain(int argc, _TCHAR* argv[]){ system("pause"); return 0;}*///10.8.3 使用关联容器//STL/CLR中的甩的关联容器的使用方式基本上与等价的本地STL容器相同,但是有一个重要的小区别,通常在处理对象的表示方式方面//首先,我们存储在类型映射中的元素的类型//map //在本地STL中的类型pair ,但是在STL/CLR映射容器中它是类型map ::value_type,//它是一个数值类型,这暗示了我们不再能用make_pair()函在STL/CLR中创建映射条目,取而代之的是使用map 类中定义的静态make_value()函数//第二,在map 中插入一个元素的insert()函数对于本地STL容器返回一个类型pair ::iterator, bool>类型的值,而对于STL/CLR map 容器,insert()函数返回下面的这个类型的值//map ::pair_iter_bool//它是一个引用类型,类型map ::pair_iter_bool的对像有两个公有字段,first和second//first是下面类型的迭代器的一个句柄//map ::iterator^//second的类型为bool,如果second的值为true,那么first就指向新插入的元素,否则它指向映射中已经存在的具有相同键的元素//10.9 小结//STL和STL/CLR功能,包括容器,迭代器,算法和函数对像的模板//容器是一个存储和组织其他对像的类,序列容器用一个序列(如数组)存储对像,关联容器存储是键/对像对的元素,其中键确定对存储在容器中的何处//迭代器是行为与指针相似的对像,对中的迭代器用来通过一个半开放的间隔定义一个对像集合,其中第一个迭代器指向系列中的第一个对像,第二个迭代器指向系列中最后一个对像的下一个位置//流迭代器是允许我们访问或修改流中的内容的迭代器//迭代器有四大类,输入和输出迭代器,前向迭代器,双向迭代器和随机访问迭代器,迭代器这几类中每一类都提供了比上一类更多的功能,因此输入和输出迭代器提供的功能性最小,随机访问迭代器提供的功能性最大//算法是在一对迭代器指定的一个对像序列上操作的模板函数//函数对像是重载()运算符(通过在类中实现函数operator()())的类型的对像,STL和STL/CLR定义用于容器和算法的广泛类型的标准迭代器,我们也可以写自己的类来定义函数对像) 运算,例如:less>