C++ 为什么是';可变的';lambda函数属性,而不是捕获类型?

C++ 为什么是';可变的';lambda函数属性,而不是捕获类型?,c++,c++11,C++,C++11,为什么c++11要求我们编写: [a,b]() mutable { a=7; } // b is needlessly mutable, potential source of bugs 而不是: [mutable a,b]() { a=7; } // no problems here 这是一种被认为不够重要的疏忽,还是有具体的技术原因?可能是某种疏忽(与不能使用右值引用的方式相同),是lambda概念实现方式的产物 int a; int* b; float c; auto lamb

为什么c++11要求我们编写:

[a,b]() mutable { a=7; } // b is needlessly mutable, potential source of bugs
而不是:

[mutable a,b]() { a=7; } // no problems here
这是一种被认为不够重要的疏忽,还是有具体的技术原因?

可能是某种疏忽(与不能使用右值引用的方式相同),是lambda概念实现方式的产物

int   a;
int*  b;
float c;

auto lambda1 = [&a, b, c](int d) mutable -> void {};

class lambda1 {
public:
    void operator()(int d) {}
private:
    int&  a_;
    int*  b_;
    float c_;
};

auto lambda2 = [&a, b, c](int d) -> void {};

class lambda2 {
public:
    void operator()(int d) const {}
private:
    int&  a_;
    int*  b_;
    float c_;
};

mutable
关键字适用于lambda表达式生成的对象,而不适用于单独捕获的项,因此编译器可以使用
operator()
方法上的
const
修饰符来实现它,如本标准第5.1.2节第5段所述

此函数调用运算符声明为常量(9.3.1),当且仅当 lambdaexpression的参数声明子句后面没有 易变的

在您的示例中,lambda表达式生成的类可能如下所示:

class lambda
{
  int a, b;

public:

  lambda( int a, int b ) : a( a ), b( b ) {}

  void operator()() // non-const due to mutable keyword
  {
    a = 7;
  }
};

以下内容提到了您的建议:

lambda表达式的语法可以扩展为允许声明 闭包成员是否应该声明为可变的

这种方法可能会让程序员感到困惑,因为易变性不是一个问题 属性,而不是存储在 结束。

我不知道这是否是唯一的原因,但它确实似乎是被考虑过的。
然而,在年,他建议去掉
mutable
,不要隐式地创建捕获副本
const
,因此,我们可能会再次看到变化。

与通常使用的
mutable
关键字不同,不使用
mutable
关键字:在这种情况下,它意味着与
const
相反,并应用于函数调用操作符隐式函数对象的常量。但是,隐式函数对象的函数调用操作符默认为
const
,而成员函数通常为非
const
(“可变”)但默认为。lambda函数的引入早于上下文关键字(
override
final
)的使用,
mutable
关键字似乎比
not const

更好,他知道
mutable
的作用,他在问为什么语法是这样;和常量浮点数c_;正确的?编辑:没关系,我看到op()函数是const限定的,这现在是有意义的。谢谢你指出这一点!我很高兴知道这至少是经过考虑的,即使我不认为我同意。另外,我喜欢Herb的建议,特别是如果你添加了将捕获标记为const的功能(这是通过引用捕获atm缺少的功能)。在阅读了链接文章的完整部分后,我不确定我是否完全同意这个论点(我的意思是,不仅仅是不同意,我不理解逻辑)。其主张是,由于可变性是存储在闭包中的变量的属性,而不是闭包本身的属性,因此,限定变量会令人困惑,我们应该改为运算符,从而有效地改变整个闭包的可变性。通常被这种关于潜在混淆的争论弄糊涂;)@MMONY:我也不是100%确定逻辑,但是当
mutable
应用于整个对象时,您知道在后续调用中可能会得到不同的结果。当这只应用于成员变量时,就没有闭包对象的易变性那么清楚了。@JesseGood fair argument(我知道你只是在解释):“一旦任何成员变为易变的,整个闭包的易变性就会改变。”。但是,通过引用捕获lambda已经影响了“可变性”(后续调用可能返回不同的值),但不需要关键字。通过值等捕获指针也是如此。无论如何,程序员都必须知道每个变量是如何捕获的。@mmocny:我同意这不是一个强有力的论点。但是,请注意,通过引用捕获,闭包对象被认为没有状态,因为状态存储在闭包之外
mutable
是表示闭包状态的属性,因此在没有状态时不需要它。他问为什么不能将单个成员标记为可在常量函数体中使用,而不是完全删除常量函数。