笔记2-容器适配器/泛型算法/lambada表达式

容器适配器 

容器适配器  stack quque priority_quque 接受一种已有的容器类型,使其行为看起来像另一种容器

stack及queue基于deque,priority_quque基于vector


PS:介绍下value_type: 表示容器中的元素类型,该方法叫做type traits。见源代码

template<typename T...>
vector {
 typedef T value_type; //即value_type就是容器内部的一个typedef,因为T可以有int string float等,
			//因此为了表示方便,统一用value type表示
...				
}

一、栈的特殊操作



二、Queue与Priority_Queue特殊操作



三、泛型算法

算法通常是通过迭代器来使用的
算法本身不会执行容器操作,只会运行于迭代器之上,执行迭代器的操作。

accumulate(it1,it2,初始值) 求和
其中序列中元素的类型必须与第三个参数匹配,或者能够转换为第三个参数的类型
也可以用在string上
string s = accmulate(v.begin(),v.end(),string("XX"); //注意这里显示的创建了一个string对象,
 //原因在于,若只是写成"XX",那么则成为了const char*,而const char*没有+运算符	


  
  
equal(v1.cbegin(), v1.cend() , v2.cbegin()) 比较v1,v2两序列是否有对应相等,相等返回true,否则返回false注意这里元素类型可以不一样,如v1可以为string,v2可以为const char*。fill(v1.begin(), v1.end() , value)填充序列范围的值fill_n (it,n,value) 填充从it位置开始n个位置的值为valueback_inserter插入迭代器确保算法有足够的元素存储输出数据的一种方法是使用插入迭代器。插入迭代器是可以给基础容器添加元素的迭代器。
vector<int> v;
fill_n(back_inserter(v),3,0); \\这样v就有了3个元素


vector<int> v;            
auto i = back_inserter(v); \\这样v就有了一个20的元素
*i = 20;    

copy (v1.begin(), v1.end() , v2.begin()) 复制
前两个参数为被拷贝序列的范围,第三个参数为目的序列的起始位置

replace(v1.begin(), v1.end() , value1,value2)
前两个参数为序列范围,value1表示要搜索的值,value2表示要替换成的值

replace_copy(v1.begin(), v1.end() , v2,value1,value2)
前两个参数为序列范围,第三个参数表示调整后序列的保存位置,value1表示要搜索的值,value2表示要替换成的值

vector<int> ivec;
replace_copy (ilst.begin(), ilst.end(), back_inserter(ivec), 0, 42); \\ilist未改变,ivec存有ilist的一个副本,
								      \\但ilist内所有的0在ivec中都变成了42



排序
sort(b,e) 默认从小到大排列
sort (b ,e ,谓词函数)   \\ 谓词函数可自定义比较形式,且该函数参数也必须为2个,且参数类型与元素类型要相同
unique( b,e) 重复排序:使用unique前要先进行排序,最后返回值指向最后一个不重复值之后的部分,但重复值实际上并未删除,因为算法并不对容器进行操作,不能添加或删除元素,如若要删除可使用erase
stable_sort 稳定排序,即在元素相等的情况下不会改变原有位置,而sort可能会改变原有顺序

find_if(b,e,谓词函数)

函数带有一对迭代器形参,指定其操作的范围。该函数还带有第三个形参,表明用于检查范围内每个元素的谓词函数。find_if 返回一个迭代器,指向第一个谓词函数返回非零值的元素。如果这样的元素不存在,则返回第二个迭代器实参。

for_each( b , e , 谓词函数)


lambada表达式:可定义在函数内部

[捕获列表](参数列表) ->返回类型 {函数体} 

捕获列表指的是lambada所在函数中定义的局部变量的列表,只有在捕获列表中捕获一个它所在函数中的局部变量(非static,若为static变量或所在函数之外声明的名字则可以直接定义),才能在lambada中使用该变量

可以省略参数列表与返回类型,但必须包含捕获列表与函数体

lambada值捕获的方式:被捕获的变量的值是在lambada创建时拷贝,而不是调用时拷贝

void func()
{
int x = 10;
auto f = [x]{return x;};
x = 5;
auto j = f(); //j此时为10,而不是5,f保存了我们创建他时x的拷贝

引用捕获:

void func()
{
int x = 10;
auto f = [&x]{return x;};
x = 5;
auto j = f(); //j此时为5,而不是10,因此是引用

隐式捕获:

可在捕获列表中直接写&或=,&表示都采用引用捕获,=表示都采用值捕获



默认情况下,值捕获时其值不允许发生改变,如需改变需要加上mutable

int x;
auto i = [x]{return ++x;}; //编译不通过
auto j = [x] mutable {return ++x;}

lambada尾置返回类型

transform(v1.begin(),v1.end(),v2.begin(),
[](int i){if(i<0) return -i; else return i;};
//编译不会通过,实际返回的是int,但编译器可能推断为void,因此需要指定返回类型(尾置返回)
正确写法如下:
transform(v1.begin(),v1.end(),v2.begin(),
[](int i) -> int  
{if(i<0) return -i; else return i;};

bind绑定

auto newFun = bind(oldFun,arg_list);

参数oldFun是需要bind封装的源函数,newFun是封装了参数后的old_Fun,arg_list是一个逗号分割的参数列表,对应oldFun的参数,即当我们调用newFun是,它会调用oldFun并且会把参数列表中的参数传给oldFun 
arg_list中会包含_n的名字,此类名字的参数又名”占位符”,因为其占据了newCallable的参数的位置,其中_n中的n表示它占据了new_Fun函数中的第几个参数。 

auto new_func = bind ( old_func, a,b,_1,c,_2)

new_func(X, Y )  ==> old_dunc(a,b,X,c,Y)


用bind重排源函数的参数顺序

用bind重排源函数的参数顺序只需将新函数与源函数的参数列表进行跌倒即

//假定源函数如下
bool oldFun(int a1,int a2);

//使用bind封装源函数如下
auto newFun = bind(old_Fun,_2,_1);

使用ref给源函数传递引用参数
如果我们想像lambda表达式一样传递引用,那么就得使用标准库中的ref函数,与其类似的是cref其生成的引用是const类型的 

for_each(v.begin(),v.end(),bind(old_func, ref(os),_1,' ' );



插入迭代器

back_inserter

front_inserter

inserter

iostream迭代器

istream_iterator

ostream_iterator

反向迭代器


迭代器分类



list、forward_list特殊操作






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值