为什么'可变'是一个lambda函数属性,而不是一个捕获types?

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

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

代替:

 [mutable a,b]() { a=7; } // no problems here 

这是一个疏忽,认为不够重要,还是有特定的技术原因?

关于你在n2651的build议有一个提到:

lambdaexpression式的语法可以扩展为允许声明闭包成员是否应声明为mutable。

这种方法可能会让程序员感到困惑,因为可变性不是闭包对象的属性,而是存储在闭包中的variables。

我不知道这是否是唯一的原因,但似乎是这样。 但是,在Herb Sutter的提议中 ,他build议摆脱可mutable而不是使捕获副本隐含地为const ,所以我们可能会再次看到变化。

可能是一种监督(就像不能使用右值参考一样),这是一种lambdas在概念上被实现的方式。

 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关键字适用于由lambdaexpression式生成的对象,而不是单独捕获的项目,以便它可以由编译器在operator()方法上使用const修饰符来实现,如标准的第5.1.2节第5段。

这个函数调用操作符被声明为const(9.3.1)当且仅当lambdaexpression式的参数声明子句没有跟随可变。

在您的示例中,由lambdaexpression式生成的类可能如下所示:

 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; } }; 

mutable关键字不像通常使用的mutable关键字那样使用:在这种情况下,它的意思是与const相反,并且适用于函数调用操作符的隐式函数对象的const 。 但是,默认情况下隐式函数对象的函数调用操作符是const ,而通常成员函数是非常量(“可变”),但是是默认的。 lambda函数的引入早于上下文关键字( overridefinal )的使用,而mutable关键字似乎是比not const更好的select。