c++11 - C++14 通用 lambda 捕获的 C++11 仿真与可变说明符之间的关系
问题描述
在 Effective Modern C++ 第 32 条的第 227-228 页,Scott Meyers 提出了以下代码块,作为解决C++11 中缺乏通用 lambda 捕获的一种方法。
// data is in scope
auto func =
std::bind(
[](const std::vector<double>& x) // I've renamed it x so there's no ambiguity in my description below
{ /* usses of x */ },
std::move(data)
);
然后他发表了以下评论,我总体上不太了解。
默认情况下,
operator()
从 lambda 生成的闭包类中的成员函数是const
.const
这具有在 lambda 主体内呈现闭包中的所有数据成员的效果。data
但是,绑定对象内部的移动构造副本不是const
,因此为了防止该副本data
在 lambda 内部被修改,将 lambda 的参数声明为 reference-to-const
。如果 lambda 被声明mutable
,则operator()
在其闭包类中不会被声明const
,并且const
在 lambda 的参数声明中省略是合适的:// data is in scope auto func = std::bind( [](std::vector<doubld>& x) mutable // ditto { /* uses of x */ }, std::move(data) );
我试图打破它:
- (非
mutable
)lambda 闭包具有operator()
成员函数const
, - 因此他们不能修改捕获的变量;
(然而,那个 lambda 首先没有捕获任何东西,所以以下几点似乎与我无关......)
std::bind
data
在对象的非const
成员变量中复制(嗯,移动)func
;- 由于 lambda 通过引用获取参数(而不是通过值,因为整点是模拟 C++14 的 move-lambda 捕获),因此程序员可以
data
通过x
lambda 的主体内部进行修改(这可能是无意的); - 为避免这种情况,制作了参数
const&
。
所以,如果声明了 lambda [...],我不明白最后一个时期的意义。
解决方案
好的,写这个问题帮助我理解我只是忽略了该代码的最初动机:模拟广义 lambda 捕获。
也许 Scott Meyers 还暗示,该代码的编写者很自然地希望绑定对象func
的行为类似于所需的 lambda ,因为它使用与存储在其中的实际 lambdafunc
相同的说明符进行编码(实际上文本仅指说明mutable
符,可能是因为这是唯一值得讨论的)。
换句话说,
- 看到通过
mutable
存储在内部的非lambda ,程序员可能期望它将表现为相应的非C++14 lambda,因此实际 lambda 的参数存储在;func
std::bind
func
mutable
const
func
- 如果实际的 lambda 是
mutable
,那么用户希望func
表现得像对应的mutable
C++14 lambda,所以他不希望它保留未修改的捕获值,因此const
在第二块代码中缺少。
更短:
存储在其中的非mutable
lambdafunc
不应修改其参数,因为相应的所需非mutable
C++14 lambda 不会修改其捕获的变量。
推荐阅读
- flutter - 如何在flutter中在一定时间内执行一个方法?
- reactjs - 删除列表后添加点击事件
- java - 使用 thymeleaf 在 javascript 中使用嵌套的 HashMap 值迭代 HashMap
- python - 如何突出显示matplotlib中折线图的最低线?
- javascript - 有没有办法构建跨平台桌面应用程序(Mac/Windows)来处理打印作业?
- python - 如何从不同的设备连接到我的 python 套接字服务器?
- kubectl - 如何仅列出来自 kubectl 输出的主节点?
- javascript - C# asp.net mvc 中 Chart.js 的行不起作用
- python - 带有 WebRTC 的 OpenCV python 建模服务器
- c++ - 如何将python dict发送到C++