C++の基礎 - クロージャ
ナビゲーションに移動
検索に移動
概要
C++では、クロージャを作成することができる。
クロージャとは、環境(状態)を持った関数オブジェクトのようなものである。
作成のポイントとして、ラムダ式をコピーキャプチャとした上でmutableにすることである。
クラスのメンバ変数等を使用せずに状態を保持できるため、大変便利なものといえる。
サンプルコード
#include <iostream>
auto func()
{
int x = 0;
return [=]() mutable -> void
{
x++; std::cout << x << std::endl;
};
}
int main()
{
auto f1 = func();
f1();
f1();
f1();
auto f2 = func();
f2();
f2();
f2();
}
出力 1 2 3 1 2 3
環境を共有する複数の処理を行う場合、引数で場合分けをする方がよい。
なお、参照キャプチャは、オブジェクトを複数個生成する場合は使用できない。
#include <iostream>
auto func()
{
int x = 0;
return [=](std::size_t mode = 0) mutable -> void
{
switch(mode)
{
case 1:
++x;
std::cout << x << std::endl;
break;
case 2:
--x;
std::cout << x << std::endl;
break;
default:
std::cout << x << std::endl;
break;
}
};
}
int main()
{
auto f1 = func();
auto f2 = func();
f1(1); // 1
f2(1); // 1
f1(2); // 0
f2(1); // 2
f1(1); // 1
f2(2); // 1
f1(2); // 0
f2(2); // 0
f1(); // 0
f2(); // 0
}
処理を関数ごとに分ける場合、bind関数等は新しく関数を生成しているため、環境が共有されず使用できない。
処理を分ける場合は、上記のf1関数を生成した後、以下の処理を記述する。
auto inc = [&]() { return f1(1); };
auto dec = [&]() { return f1(2); };
inc();
dec();