c++11で次のように記述する必要があるのはなぜですか。
[a,b]() mutable { a=7; } // b is needlessly mutable, potential source of bugs
それ以外の:
[mutable a,b]() { a=7; } // no problems here
これは見落としであり、十分に重要ではないと考えられていますか、それとも特定の技術的理由がありますか?
n2651にあなたの提案についての言及があります:
ラムダ式の構文を拡張して、クロージャーメンバーを可変として宣言する必要があるかどうかを宣言できるようにすることができます。
可変性はクロージャーオブジェクトのプロパティではなく、クロージャーに格納されている変数であるため、このアプローチはプログラマーを混乱させる可能性があります。
これが唯一の理由かどうかはわかりませんが、考えられたようです。ただし、ハーブサッターの提案mutable
では、キャプチャコピーを暗黙的に作成せずに削除することを提案しているconst
ため、再び変更が発生する可能性があります。
おそらく、(右辺値の参照を使用できないのと同じように)ある種の見落としと、ラムダが概念的に実装される方法のアーティファクトです。
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
キーワードは、ラムダ式によって生成されたオブジェクトに適用され、個別にキャプチャされたアイテムには適用されないため、標準のセクション5.1.2、段落5で説明されているようconst
に、メソッドの修飾子を使用してコンパイラーが実装できます。operator()
この関数呼び出し演算子は、lambdaexpressionのparameter-declaration-clauseの後にmutableが続かない場合にのみ、const(9.3.1)として宣言されます。
あなたの例では、ラムダ式によって生成されたクラスは次のようになります。
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
override
final
mutable
not const