c++ - 当一个右值引用被副本捕获时会发生什么?
问题描述
如果我有
std::function<int()> &&x = [] { return 1; };
auto lambda = [y = x(), x] {
return y * x();
};
x
inside lambda
: std::function<int()>
, std::function<int()>&
or的类型是什么std::function<int()>&&
?如果是第一个,捕获的x
初始化是由移动构造函数还是由副本初始化的(我需要[y = x(), x = std::move(x)]
移动它)?
解决方案
什么是
x
内部类型lambda
x
被复制捕获,并且在闭包类型中声明的数据成员的类型将是std::function<int()>
. [expr.prim.lambda.capture]/10
(强调我的)
对于通过副本捕获的每个实体,在闭包类型中声明了一个未命名的非静态数据成员。...如果实体是对对象的引用,则此类数据成员的类型是引用类型,...
和
x
是由移动构造函数还是由副本初始化捕获的(我需要[y = x(), x = std::move(x)]
移动它)?
是的,您必须x = std::move(x)
明确编写,否则x
将被复制构造,因为捕获的对象x
本身就是一个左值。
以及为什么decltype(x)
会导致 type std::function<int()>&&
,因为x
这里指的x
是 lambda 之前定义的局部变量。[expr.prim.lambda.capture]/11
(强调我的)
lambda-expression 的复合语句中的每个 id-expression 是对由 copy 捕获的实体的 odr 使用,都被转换为对闭包类型的相应未命名数据成员的访问。
[注 7:不是 odr-use 的 id-expression 指的是原始实体,而不是闭包类型的成员。但是,这样的 id-expression 仍然会导致实体的隐式捕获。——尾注]
BTW(x)
不是id 表达式,x
这里指的是闭包类型的成员。然后decltype((x))
导致类型const std::function<int()> &
(因为(x)
它是一个左值表达式并且operator()
lambda 是 const 限定的;对于mutable
lambda 它将是std::function<int()> &
)。
推荐阅读
- mysql - 如何从两个表中删除对等记录?
- node.js - 关于nodejs的东西?
- android - 使用 ContentProvider 在应用启动时运行代码
- javascript - webpack缓存渲染的index.html加载不好,加载scss失败
- esp8266 - NodeMCU 闪存失败 - “连接到 HW-BELTLINE-01”
- c++ - 关于 c++ 中 char 数据类型的问题
- java - 创建输入框控件布尔值
- reactjs - 在 React Native 挂钩中动态更新上下文
- c++ - 使用 final_suspend 进行延续的 C++20 协程
- javascript - 添加到数组 - 没有重复字段值的子文档