《C++primer》第10章:泛型算法

初始泛型算法

举例了几个常见算法...

只读算法最好使用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执行时变量仍然存在

一般来说,应尽量减少捕获的数据量,避免潜在捕获导致的问题

隐式捕获

《C++primer》第10章:泛型算法_第1张图片

可变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)中参数的位置

《C++primer》第10章:泛型算法_第2张图片

以此类推,使用bind可以把多参数的函数适配为少参数的函数

《C++primer》第10章:泛型算法_第3张图片

使用placeholder名字

上面bind中的_n参数都是定义在std::placeholder中的,使用时需要声明

bind参数

可用bind绑定给定调用对象的参数或重新安排参数顺序,如

此外,bind可绑定引用参数

你可能感兴趣的:(《c++,primer》)