专栏首页C++核心准则原文翻译C++核心准则F.52:在lambda表达式中使用引用形式捕捉局部变量

C++核心准则F.52:在lambda表达式中使用引用形式捕捉局部变量

F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms

F.52 在lambda表达式中使用引用形式捕捉局部变量,包含向算法传递变量的情况。

译者注:如果你不清楚捕捉(capture)是什么,请参考

https://mp.weixin.qq.com/s/VuW_5OcX7uUUrMbsN2wxPQ

Reason(原因)

For efficiency and correctness, you nearly always want to capture by reference when using the lambda locally. This includes when writing or calling parallel algorithms that are local because they join before returning.

为了效率和正确性,在本地使用lambda表达式时,你差不多总是需要通过引用方式捕捉变量。这包括编写或者调用本地并发算法的情况,因为它们需要在返回前汇合(从而保证安全性,译者注)。

Discussion(讨论)

The efficiency consideration is that most types are cheaper to pass by reference than by value.

关于效率的考虑:对于大多数类型来说,传引用都会比传值的成本更低。

The correctness consideration is that many calls want to perform side effects on the original object at the call site (see example below). Passing by value prevents this.

关于正确性的考虑:许多调用都希望(在被调用函数被执行的同时,)对处于调用侧的原始对象产生连带效果(参考下面的示例)。传值做不到这一点。

Note(注意)

Unfortunately, there is no simple way to capture by reference to const to get the efficiency for a local call but also prevent side effects.

不幸的是,对于局部调用,不存在简单的方法可以通过引用捕捉常量类型变量获得效率又可以避免连带效果。

译者注:常量类型应用应该指的是在函数声明中的被声明为常量的引用参数,通过这种方式可以同时提供高效率和写保护。

Example(示例)

Here, a large object (a network message) is passed to an iterative algorithm, and is it not efficient or correct to copy the message (which may not be copyable):

这里,一个大对象(一个网络消息)传递给一个迭代算法,拷贝该消息不是高效或者正确的做法(它也许不能拷贝):

std::for_each(begin(sockets), end(sockets), [&message](auto& socket)
{
    socket.send(message);
});

译者注:每次循环都拷贝的代价也很高。

Example(示例)

This is a simple three-stage parallel pipeline. Each stage object encapsulates a worker thread and a queue, has a process function to enqueue work, and in its destructor automatically blocks waiting for the queue to empty before ending the thread.

这是一个简单的三阶段并发管道。每个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

Enforcement(实施建议)

Flag a lambda that captures by reference, but is used other than locally within the function scope or passed to a function by reference. (Note: This rule is an approximation, but does flag passing by pointer as those are more likely to be stored by the callee, writing to a heap location accessed via a parameter, returning the lambda, etc. The Lifetime rules will also provide general rules that flag escaping pointers and references including via lambdas.)

标记lambda表达式采用引用方式捕获变量,但是没有在函数范围内本地使用,或者通过引用方式传递给另外一个函数的情况。

注意:这是一个近似的规则,但是确实可以标记出:通过很有可能被调用者保存的指针进行的传递,对通过参数访问的堆上的某处进行的写入,返回lambda表达式等等。生命周期准则群组也会提供标记逃逸指针和参照的普遍准则,也会包含源自lambda表达式的情况。

觉得本文有帮助?请分享给更多人

关注【面向对象思考】,每天前进一小步

有任何疑问,欢迎留言提问或讨论


面向对象设计,面向对象编程,面向对象思考!

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++核心准则​SF.8:为所有的.h文件使用包含监护​

    SF.8: Use #include guards for all .h files

    面向对象思考
  • C++核心准则ES.65:不要解引用无效指针

    Dereferencing an invalid pointer, such as nullptr, is undefined behavior, typica...

    面向对象思考
  • C++核心准则ES.24: 使用unique_ptr<T>管理指针

    Using std::unique_ptr is the simplest way to avoid leaks. It is reliable, it mak...

    面向对象思考
  • 在Coq中量子电路的符号推理(CS PL)

    量子电路是将输入量子态转换为输出量子态的计算单元,解释其行为的一种常见方法是显式地计算由其实现的酉矩阵。然而,随着量子位数的增加,矩阵维数呈指数增长,计算将变得...

    Elva
  • what is telnet?

    Note: SSH is required to establish remote terminal connections to Indiana Univer...

    ke1th
  • SAP S/4 HANA新变化-PP生产计划

    1、BOM, Routing, Production Version With SAP S/4HANA, on-premise edition 1511, th...

    SAP最佳业务实践
  • [Golang] 初探之 sync.Once

    Once 官方描述 Once is an object that will perform exactly one action,即 Once 是一个对象,它提...

    landv
  • 拼多多成立技术顾问委员会,陆奇将领导相关工作

    美国东部时间 3 月 13 日上午,拼多多(NASDAQ:PDD)公布了截止 2018 年 12 月 31 日的第四季度和全年年的未经审计财务业绩。

    AI科技大本营
  • 使用调试的方式搞清楚SAP UI5应用标题的更改方式

    In Fiori launchpad, the page title will display default value “Home”. When I cli...

    Jerry Wang
  • 面向非标准到达过程的多服务器系统人员配备(CS P)

    服务系统的到达过程通常显示(i)大于预期的波动,(ii)时变率和(iii)时间相关性。因此,我们引入了一种结合了这三个特征的特定非均匀泊松过程。最终的到达过程将...

    蔡秋纯

扫码关注云+社区

领取腾讯云代金券