举例了几个常见算法...
只读算法最好使用const迭代器,除非想对返回的迭代器再进行其它操作
那些只接受一个单一迭代器来表示第二个序列的算法,都假定第二个序列至少和第一个序列一样长
向目的迭代器写入的算法都假定目的的位置足够大,若位置不足,则结果未定义
可向算法传递谓词,让算法按照我们自己定制的比较标准进行比较
lambda表达式:
理解为未命名的内联函数
与普通函数不同,它可定义在函数内部
与普通函数不同,必须使用尾置返回来指定返回类型
若lambda的函数体包含任何单一return语句之外的内容,且未指定返回类型,则返回void
lambda不能有默认参数
使用捕获列表
int t1 = 5, t2 = 10;
auto fff = [t1, t2] (const string &a) {
if (a.length() >= t1 && a.length() <= t2) return true;
else return false;
};
cout << fff("1234") << endl; //输出0
cout << fff("123456") << endl; //输出1
只有在捕获列表中的局部变量,lambda才可以使用,其它局部变量不能使用
捕获列表只适用于局部非static变量,lambda可直接使用函数外定义的变量和局部static变量
lambda捕获与返回
当定义一个lambda时,编译器会生成一个与lambda对应的新的类类型
当向函数传递一个lambda时,同时定义了一个新类型和这个类型的对象,传递的参数就是编译器生成的未命名的对象
默认情况下,从lambda生成的类都包含所捕获变量的数据成员,它们在lambda对象创建时被初始化
值捕获
与参数不同,捕获的值在lambda创建时就被拷贝,因此下面代码输出的是5
int t1 = 5;
auto fff = [t1] () {
return t1;
};
t1 = 3;
auto temp = fff();
cout<
引用捕获
引用捕获的是引用所绑定的对象,因此下面代码输出的是3
int t1 = 5;
auto fff = [&t1] () {
return t1;
};
t1 = 3;
auto temp = fff();
cout<
当以引用捕获一个变量时,必须确保在lambda执行时变量仍然存在
一般来说,应尽量减少捕获的数据量,避免潜在捕获导致的问题
隐式捕获
可变lambda
值捕获中,若希望改变一个被捕获的变量的值,则必须在参数列表首上加上关键字mutable
int t1 = 5;
auto fff = [t1] () mutable{
t1 = 3;
return t1;
};
auto temp = fff();
cout<
引用捕获中,捕获变量是否可修改取决于变量是否为const
指定lambda返回类型
若lambda包含return之外的任何语句,则编译器假定此lambda返回void,若想返回其它类型,需要使用尾置返回类型
参数绑定
对于一两个地方使用的简单操作,lambda比较适合
对于很多地方使用的,则函数比较适合
一般的无捕获参数的lambda都比较容易转换成函数
但有捕获参数的lambda就不容易转换成函数,因为一些算法一般接受一元谓词,多参数的函数不能用于算法,因此,需要借助以下函数
标准库bind函数
表示生成的可调用对象(即newCallable)中参数的位置
以此类推,使用bind可以把多参数的函数适配为少参数的函数
使用placeholder名字
上面bind中的_n参数都是定义在std::placeholder中的,使用时需要声明
bind参数
可用bind绑定给定调用对象的参数或重新安排参数顺序,如
此外,bind可绑定引用参数