標準では、このコードで何が起こるかを定義していますか?C++のラムダ式で値を取得するには、ラムダオブジェクトで値をコピーする必要がありますか?
#include <iostream>
template <typename Func>
void callfunc(Func f)
{
::std::cout << "In callfunc.\n";
f();
}
template <typename Func>
void callfuncref(Func &f)
{
::std::cout << "In callfuncref.\n";
f();
}
int main()
{
int n = 10;
// n is captured by value, and the lambda expression is mutable so
// modifications to n are allowed inside the lambda block.
auto foo = [n]() mutable -> void {
::std::cout << "Before increment n == " << n << '\n';
++n;
::std::cout << "After increment n == " << n << '\n';
};
callfunc(foo);
callfunc(foo);
callfuncref(foo);
callfunc(foo);
return 0;
}
グラムの++とこれの出力は次のようになります。
$ ./a.out
In callfunc.
Before increment n == 10
After increment n == 11
In callfunc.
Before increment n == 10
After increment n == 11
In callfuncref.
Before increment n == 10
After increment n == 11
In callfunc.
Before increment n == 11
After increment n == 12
は標準で必要とされるこの出力のすべての機能はありますか?
特に、ラムダオブジェクトのコピーが作成された場合、取得されたすべての値もコピーされるように見えます。しかし、ラムダオブジェクトが参照渡しされた場合、取得された値はコピーされません。また、関数が呼び出される直前にはキャプチャされた値のコピーが作成されないので、キャプチャされた値への変更がコール間で保持されます。
これらのラムダ相当のクラスには、コンストラクタの移動と割り当て操作の移動もありますか? – Omnifarious
@Omnifarious:コンストラクタを移動する:「たぶん」(5.1.2/19:「暗黙的に宣言された移動コンストラクタがあるかもしれません)」ラムダには代入演算子がなく、削除されます。 – kennytm