本篇文章为大家展示了如何在lambda表达式中使用引用形式捕捉局部变量,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获
创新互联公司主要从事成都做网站、网站制作、网页设计、企业做网站、公司建网站等业务。立足成都服务文圣,十载网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18982081108
F.52 在lambda表达式中使用引用形式捕捉局部变量,包含向算法传递变量的情况。
译者注:如果你不清楚捕捉(capture)是什么
Reason(原因)
为了效率和正确性,在本地使用lambda表达式时,你差不多总是需要通过引用方式捕捉变量。这包括编写或者调用本地并发算法的情况,因为它们需要在返回前汇合(从而保证安全性,译者注)。
关于效率的考虑:对于大多数类型来说,传引用都会比传值的成本更低。
关于正确性的考虑:许多调用都希望(在被调用函数被执行的同时,)对处于调用侧的原始对象产生连带效果(参考下面的示例)。传值做不到这一点。
不幸的是,对于局部调用,不存在简单的方法可以通过引用捕捉常量类型变量获得效率又可以避免连带效果。
译者注:常量类型应用应该指的是在函数声明中的被声明为常量的引用参数,通过这种方式可以同时提供高效率和写保护。
这里,一个大对象(一个网络消息)传递给一个迭代算法,拷贝该消息不是高效或者正确的做法(它也许不能拷贝):
std::for_each(begin(sockets), end(sockets), [&message](auto& socket){ socket.send(message);});
译者注:每次循环都拷贝的代价也很高。
这是一个简单的三阶段并发管道。每个state对象封装一个工作线程和一个队列,有一个process函数处理入队,它的析构函数在关闭线程之前自动地进入阻塞状态以等待队列变空。
void send_packets(buffers& bufs){ stage encryptor([] (buffer& b){ encrypt(b); }); stage compressor([&](buffer& b){ compress(b); encryptor.process(b); }); stage decorator([&](buffer& b){ decorate(b); compressor.process(b); }); for (auto& b : bufs) { decorator.process(b); }} // automatically blocks waiting for pipeline to finish
译者注:代码中使用的是隐式捕捉,具体可以参考:https://mp.weixin.qq.com/s/RNpLqwekN3BJUbIN-DwVxQ
标记lambda表达式采用引用方式捕获变量,但是没有在函数范围内本地使用,或者通过引用方式传递给另外一个函数的情况。
注意:这是一个近似的规则,但是确实可以标记出:通过很有可能被调用者保存的指针进行的传递,对通过参数访问的堆上的某处进行的写入,返回lambda表达式等等。生命周期准则群组也会提供标记逃逸指针和参照的普遍准则,也会包含源自lambda表达式的情况。
上述内容就是如何在lambda表达式中使用引用形式捕捉局部变量,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。