C++11 C与x2B之间的关系+;11模拟C++;14广义lambda捕获和可变说明符 在有效的现代C++项目32的第227到228页中,Scott Meyers提出了以下代码,作为解决C++ 11中缺少的方法。 //数据在范围内 自动功能= 绑定( [](const std::vector&x)//我已将其重命名为x,因此在下面的描述中没有歧义 {/*x的用法*/}, 标准::移动(数据) );

C++11 C与x2B之间的关系+;11模拟C++;14广义lambda捕获和可变说明符 在有效的现代C++项目32的第227到228页中,Scott Meyers提出了以下代码,作为解决C++ 11中缺少的方法。 //数据在范围内 自动功能= 绑定( [](const std::vector&x)//我已将其重命名为x,因此在下面的描述中没有歧义 {/*x的用法*/}, 标准::移动(数据) );,c++11,lambda,c++14,C++11,Lambda,C++14,然后他发表了以下评论,我不太明白 默认情况下,从lambda生成的闭包类中的操作符()成员函数是const。其效果是呈现lambda主体内闭包const中的所有数据成员。绑定对象内的数据的移动构造副本不是常量,但是,为了防止数据的副本在lambda内被修改,lambda的参数声明为引用-常量。如果lambda被声明为mutable,则其闭包类中的操作符()将不会被声明为const,并且在lambda的参数声明中省略const是合适的: //数据在范围内 自动功能= 绑定( [](std::vec

然后他发表了以下评论,我不太明白

默认情况下,从lambda生成的闭包类中的
操作符()
成员函数是
const
。其效果是呈现lambda主体内闭包
const
中的所有数据成员。绑定对象内的
数据
的移动构造副本不是
常量
,但是,为了防止
数据
的副本在lambda内被修改,lambda的参数声明为引用-
常量
。如果lambda被声明为
mutable
,则其闭包类中的
操作符()
将不会被声明为
const
,并且在lambda的参数声明中省略
const
是合适的:

//数据在范围内
自动功能=
绑定(
[](std::vector&x)可变//同上
{/*使用x*/},
标准::移动(数据)
);
我试着把它分解:

  • (非-
    mutable
    )lambda闭包具有
    operator()
    成员函数
    const
  • 因此,他们不能修改捕获的变量
(然而,lambda一开始并没有捕获任何东西,因此以下几点似乎与我无关……)

  • std::bind
    func
    对象的非
    const
    成员变量中复制(好的,移动)
    数据
    
  • 由于lambda通过引用获取参数(而不是通过值,因为整个要点是模拟C++14的move lambda捕获),程序员可以通过lambda主体内的
    x
    修改
    数据(可能是有意的)
    
  • 为了避免这种情况,参数设置为
    const&

因此,如果lambda被声明为[…],我就不明白上一个阶段的意义了。

好吧,写这个问题让我明白,我只是忽略了代码的最初动机:模拟广义lambda捕获

Scott Meyers可能还暗示,该代码的编写者期望绑定对象
func
的行为与所需的lambda相似,因为它是使用与
func
中存储的实际lambda相同的说明符编码的(实际上,本文只引用了
可变的
说明符,可能是因为它是唯一值得讨论的说明符)

换句话说,

  • 通过
    std::bind
    查看存储在
    func
    中的非
    mutable
    lambda,程序员可能期望
    func
    将表现为相应的非
    mutable
    C++14 lambda,因此存储在
    func
    中的实际lambda参数的
    const
  • 如果实际lambda是
    mutable
    ,那么用户希望
    func
    表现为相应的
    mutable
    C++14 lambda,因此他不希望它保持捕获的值不被修改,因此在第二个代码块中缺少
    const
甚至更短:

存储在
func
中的非
mutable
lambda不应修改其参数,因为相应的所需非
mutable
C++14 lambda不会修改其捕获的变量