第10章 泛型算法
10.3.2 lambda表达式
[capture list](parameter list)->return type {function body}
/**********************************
其中,capture list(捕获列表)是一个lambda所在函数中定义的局部变量的列表(通常为空);return type、parameter list和function body与任何普通函数一样,分别表示返回类型、参数列表和函数体。但是与普通函数不同,lambda必须使用尾置返回来指定返回类型。
尾置返回类型跟在形参列表后面并以一个->符号开头
***********************************/
//通常可以忽略参数列表和返回类型,但必须包含捕获列表和函数体;
auto f = [] { return 42; };
3. 与普通函数不同,lambda不能有默认参数;
4. 一个lambda只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数中使用该变量;
[sz](const string &a)
{ return a.size() >= sz; };
10.3.3 lambda捕获和返回
//sz为隐式捕获,值捕获方式
wc = find_if(words.begin(), words.end(),
[=](const string &s){ return s.size()>=sz; });
4. 当混合使用隐式捕获和显式捕获时,捕获列表中的第一个元素必须是一个&或=,并且显式捕获的变量必须使用与隐式捕获不同的方式;
5. 可变lambda:默认情况下,对于一个值被拷贝的变量,lambda不会改变其值。通过在参数列表后加上关键字mutable,可以改变一个被捕获的变量的值;
6. 指定lambda返回类型:需要为一个lambda定义返回类型时,需使用尾置返回类型;
transform(vi.begin(), vi.end(), vi.begin(),
[](int i)->int { if(i<0) return -i; else return i;});
10.3.4 参数绑定
auto newCallable = bind(callable, arg_list);
/*****************************
其中,newCallable本身是一个可调用对象,arg_list是一个逗号分隔的参数列表,对应给定的callable的参数。即,当调用newCallable时,newCallable会调用callable,并传递给它arg_list中的参数。
arg_list中的参数可能包含形如_n的名字,其中n是一个整数,这些参数是“占位符”,表示newCallable的参数,它们占据了传递给newCallable的参数的“位置”。数值n表示生成的可调用对象中参数的位置:_1为newCallable的第一个参数,_2为第二个参数,依次类推。
*****************************/
auto g = bind(func, a, b, _2, c, _1);
//传递给g的参数按位置绑定到占位符,即,第一个参数绑定到_1,第二个参数绑定到_2。
2. 使用placeholders名字,名字_n都定义在一个名为placeholders的命名空间中,而这个命名空间本身定义在std命名空间中。
//例如,_1对应的using声明为:
using std::placeholders::_1;
//或
using namespace std::placehoders
3. 如果希望传递给bind一个对象而又不拷贝它,需使用标准库ref函数,cref函数生成一个保存const引用的类。
for_each(word.begin(), words.end(),
bind(print, ref(os), _1, ' '));
10.4 再探迭代器
迭代器分为:插入迭代器、流迭代器、反向迭代器和移动迭代器。
10.4.1 插入迭代器
插入器有三种类型,差异在于元素插入的位置: