STL-泛型算法(lambda、bind、多种迭代器)

C++ PRIMER 10

本章主要内容有lambda、bind和多种迭代器。

lambda和bind都应用于定制操作。

谓词:是一个可调用的表达式,其返回结果是一个能用作条件的值。标准库算法所使用的谓词分为两类:一元谓词(只接受单一参数)和二元谓词(有两个参数)

如函数指针作为参数时,调用过程中,可用其指向的函数计算。。

1)lambda:匿名函数

我们可以向一个算法传递任何类别的可调用对象。函数和函数指针就是可调用对象。

还有function和lambda,这里讨论lambda。

[capture list] (parameter list) -> return type {function body}

capture list捕获列表是一个lambda所在函数中定义的局部变量的列表;return type、parameter list和function body与普通函数一样,分别表示参数列表和函数体。

我们可以忽略参数列表和返回类型,但是必须包含捕获列表和函数体。[] { ...... };

在lambda中忽略括号和参数列表等价于指定一个空参数列表。

如果lambda的函数体中包含任何单一return语句之外的内容,且未指定返回类型,则返回void。

lambda没有默认参数,所以实参数目永远与形参数目相等。

 

lambda的捕获和返回

当定义一个lambda时,编译器生成一个与lambda对应的新的(未命名的)类类型。

当向一个函数传递一个lambda时,同时定义了一个新类型和该类型的一个对象:传递的参数就是此编译器生成的类类型的未命名对象。类似地,当使用auto定义一个用lambda初始化的变量时,定义了一个从lambda生成的类型的对象。

默认情况下,从lambda生成的类型都包含一个对应该lambda所捕获的变量的数据成员。类似任何普通类的数据成员,lambda的数据成员也在lambda对象创建时被初始化

 

类似参数传递,变量的捕获方式也可以是值或引用。

值捕获:[vi]{....};以值捕获方式捕获该lambda可访问空间中的vi。

引用捕获:[&vi]{....};以引用捕获方式捕获该lambda可访问空间中的vi。

值捕获的条件是变量可拷贝。被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝。因为是拷贝,所以不影响原来变量的值。

引用捕获时被引用的变量在lambda调用时存在。通过引用可修改原变量。有些情况下,引用捕获是必须的,如ostream,捕获os的唯一方法就是捕获其引用(或指向os的指针)。

隐式捕获:[=]{...}; [&]{...};lambda体中所使用的所有来自所在函数的实体都采用值捕获或引用捕获。

混合捕获:[=,identifier_list]{....}; [&,identifier_list]{...};lambda体中使用的所有函数的实体中,除了identifier_list之外,都采用值捕获/引用捕获。

 

可变lambda:

默认情况下,对于一个值被拷贝的变量,lambda不会改变其值。如果我们希望能改变一个被捕获的变量的值,就必须在参数列表首加上mutable。

[]mutable(){...};

 

指定lambda返回类型:

默认情况下,如果一个lambda体包含return之外的任何语句,则编译器假定此lambda返回void。与其它返回void的函数类似,被推断返回void的lambda不能返回值。

若lambda体是单一的return语句,返回一个条件表达式的结果。我们无须指定返回类型,因为可以根据条件运算符的类型推断出来。

当我们需要为一个lambda定义返回类型时,必须使用尾置返回类型。如  []()->int{...);

 

lambda表达式是std::function类型,保存时可用auto或std::function变量保存。

 

 

2)参数绑定:bind

对于那种只在一两个地方使用的简单操作,lambda表达式是最有用的。如果我们需要在很多地方使用相同的操作,通常应该定义一个函数,而不是多次编写相同的lambda表达式。

标准库bind函数:

bind定义在functional中。可以将bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。

调用bind的一般形式为: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为第二个参数,以此类推。

bind拷贝其参数,而有些情况下,只能使用引用,这时需要使用标准库ref函数或cref函数。如 bind ( print, ref(os), _1,' ');

 

 

3)迭代器

除了为每个容器定义的迭代器之外,标准库在头文件iterator中还定义了额外几种迭代器。这些迭代器包括:

-插入迭代器:

-流迭代器:

-反向迭代器:

-移动迭代器:

 

原文链接: https://www.cnblogs.com/cjj-ggboy/p/12404202.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    STL-泛型算法(lambda、bind、多种迭代器)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/371218

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月3日 上午10:40
下一篇 2023年3月3日 上午10:40

相关推荐