第3回ではラムダ式を説明します。 ラムダ式は簡単に説明すると、従来の関数オブジェクトの代わりになる機能です。 1: #include <iostream> 2: #include <vector> 3: #include <algorithm> 4: 5: using namespace std; 6: 7: struct CPrint 8: { 9: void operator()(int value) 10: { 11: cout << value << endl; 12: } 13: }; 14: 15: int main() 16: { 17: vector<int> vec; 18: 19: int i = 0; 20: while (i < 10) 21: { 22: vec.push_back(i * i);//iの2乗の値を入れる(0,1,4,9,...,81) 23: i++; 24: } 25: 26: for_each(vec.begin(), vec.end(), CPrint()); 27: 28: return 0; 29: } 7行目からのCPrintの部分がそうです。これを表示以外の機能も複数作る必要があるとなったとき、無駄に行数が増えて可読性が下がりやすいです。 [キャプチャ](引数)->戻り値の型{文} となります。従来のC++ではあまり見慣れない書き方なので戸惑うかと思いますが覚えてしまえば簡単です。 1: #include <iostream> 2: #include <vector> 3: #include <algorithm> 4: 5: using namespace std; 6: 7: int main() 8: { 9: vector<int> vec; 10: 11: int i = 0; 12: while (i < 10) 13: { 14: vec.push_back(i * i);//iの2乗の値を入れる(0,1,4,9,...,81) 15: i++; 16: } 17: 18: for_each(vec.begin(), vec.end(), [](int n)->void{cout << n << endl;}); 19: 20: return 0; 21: } 18行目のfor_eachの第3引数にラムダ式が使われています。 1: #include <iostream> 2: #include <vector> 3: #include <algorithm> 4: 5: using namespace std; 6: 7: int main() 8: { 9: vector<int> vec(10); 10: 11: //配列を乱数で初期化 12: generate(vec.begin(), vec.end(), []()->int{return rand();}); 13: 14: //配列の中身を表示 15: for_each(vec.begin(), vec.end(), [](int n)->void{cout << n << endl;}); 16: 17: //配列の合計を求める 18: int sum = 0; 19: for_each(vec.begin(), vec.end(), [&sum](int n)->void{sum += n;}); 20: 21: cout << sum << endl; 22: 23: return 0; 24: } ※12行目のgenerate関数は配列を第3引数の関数オブジェクトの方法で初期化するだけです。 [&sum](int n)->void{sum += n;} と[]内に&sumと書かれているのが分かります。つまりこれは、 [] キャプチャなし [x] xを値渡し [&x] xを参照渡し [x,&y] xを値渡し、yを参照渡し [=] 同スコープ内の外部変数を値渡し [&] 同スコープ内の外部変数を参照渡し [&,x] xを値渡し、それ以外の同スコープ内の外部変数を参照渡し 最後にラムダ式の他の使い方を軽く紹介します。 1: #include <iostream> 2: #include <functional> 3: 4: using namespace std; 5: 6: void loopPrint(function<void(void)> func, int cnt) 7: { 8: for (int i = 0; i < cnt; i++) 9: { 10: func(); 11: } 12: } 13: 14: int main() 15: { 16: //変数のように扱うことも出来る 17: auto m = []()->void{cout << "Hello World!" << endl;}; 18: 19: //引数として渡す事も可能 20: loopPrint(m, 5); 21: 22: return 0; 23: } ※loopPrintの引数のfunctionは引数、戻り値無しの関数オブジェクトを受け取るものだと思ってください。 以上でラムダ式の説明を終わります。 |