41

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

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

代替:

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

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

4

4 回答 4

18

n2651中提到了您的建议:

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

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

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

于 2012-12-27T04:23:55.213 回答
6

可能是某种疏忽(与不能使用右值引用相同的方式)和 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_;
};
于 2012-12-27T03:36:10.917 回答
5

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

当且仅当 lambda 表达式的 parameter-declaration-clause 后面没有 mutable 时,此函数调用运算符才被声明为 const (9.3.1)。

在您的示例中,由 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;
  }
};
于 2012-12-27T03:38:25.723 回答
0

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

于 2012-12-27T06:42:31.090 回答