【问题标题】:If I capture by value and don't use it will I still get a copy?如果我按价值捕获而不使用它,我还会得到一份副本吗?
【发布时间】:2013-11-12 18:37:15
【问题描述】:

我不想在 lambda 中按值捕获 shared_ptr 以确保对象的生命周期延长到调用 lambda 函数的点。

否则我实际上并不需要 shared_ptr。如果我这样做:

shared_ptr<..> sp;
sp->async_call( [sp](){} );

即使正文没有引用 sp,是否也保证会被复制?

【问题讨论】:

  • @c45207 是的,看来他基本上和我推断出一样的东西
  • 作为一般规则,您几乎可以回答任何“X 可以优化吗?”关于 C++ 的问题和另一个问题:“程序能区分吗?”
  • @R.MartinhoFernandes 大多数情况下是正确的,但有时允许 c++ 优化具有副作用的 cctor,例如返回值

标签: c++ c++11 lambda


【解决方案1】:

我会说,因为这个报价,它是有保证的。
5.1.2

21 计算 lambda 表达式时,副本捕获的实体用于直接初始化生成的闭包对象的每个对应的非静态数据成员。 (对于数组成员,数组元素以下标递增的顺序直接初始化。)这些初始化以声明非静态数据成员的(未指定)顺序执行。 [注意:这确保了破坏将以与构造相反的顺序发生。 ——尾注]

编辑:再想一想,因为对象是直接初始化的复制省略,甚至没有发挥作用。
由于§ 12.8 中复制省略的标准,太长无法发布,我不'不相信副本可以省略

请记住,std::shared_ptr 在大多数情况下不是线程安全的。

【讨论】:

  • 在我看来,“好像”规则在这种情况下是一个很大的问号,我个人不希望在 lambda 中找到ptr,因为这个ptr 的状态是甚至没有加载/访问或更改。
  • 似乎有点像询问是否可以优化 std::lock_guard ,因为它没有被引用。当然不能,因为构造函数和析构函数的效果是可观察的。出于这个原因,我认为捕获的实体必须在 lambdas 范围的末尾执行其析构函数,即使可以优化复制构造函数。
  • @BenPope 在某些情况下,即使存在副作用,也可以优化复制构造函数(以及析构函数)
  • @aaronman 复制省略可以忽略副作用,但不会干扰 RAII;当复制省略发生时,原始对象的生命周期简单地延长到两个生命周期中较长的一个,从而确保正确处理原始对象的资源。
  • 而复制省略只有在将两个对象变成一个对象时才具有打破as-if规则的权限;它不能打破 as-if 规则以将单个对象变成零个对象。
猜你喜欢
  • 2016-02-25
  • 2017-10-16
  • 1970-01-01
  • 2019-08-09
  • 2013-05-21
  • 1970-01-01
  • 1970-01-01
  • 2013-10-31
相关资源
最近更新 更多