C++のキャプチャありラムダ式でHelloWorld
昨日に続いて、C++14のラムダ式を。今回は、外部変数のキャプチャを試してみる。ついでに拡張forなども。
[コード]
#include <iostream>
#include <vector>
using namespace std;
int main()
{
const vector<string> hellos {"Hello", "World", ".\n"}; //①
//for C++1z
auto echo2 = [hellos] (string suppl) { //②
for (string word : hellos) {//③
string prt = (word.size() >4) ? word : (suppl + word); //④
cout << prt;
}
};
echo2 (" /w lambda [outer variable(s)]"); //⑤
return 0;
}
読み解き:
①const vectorにより定数文字列のリストを変数hellosとして定義。
const vector hellos = {"Hello", "World", ".\n"};
と、統合を入れても良い。
③ 外部変数hellosと引数supplを取るラムダ式をecho2として定義。
③ いわゆる拡張for(他言語のforeach)。
④ Cの三項演算子を使ってみた。
⑤ ラムダ式の呼び出し。
前回と比べると、main関数の中にラムダ式echo2が入っていることに気づくだろう。いわゆる関数内関数的にラムダ式は使える。また、以下のように、hellos,echo2を外に出してみるとエラーとなる。これは、vettor等、コレクションのメモリ管理との関係なのだろう。
#include <iostream>
#include <vector>
using namespace std;
//vectorのメモリが確保できないとエラーが出る。
const vector<string> hellos {"Hello", "World", ".\n"}; //①
//for C++1z
auto echo2 = [hellos] (string suppl) { //②
for (string word : hellos) {
string prt = (word.size() >4) ? word : (suppl + word); //③
cout << prt;
}
};
int main()
{
echo2 (" /w lambda [outer variable(s)]"); //④
return 0;
}
[処理結果]
$ make
./a.out
HelloWorld /w lambda [outer variable(s)].
[参考リンク]
(付記)Cのブロック式によるキャプチャ式は動作せず。
ちなみにclangのCで使えるブロック式(アップル社独自拡張Blocks)でも、C++のラムダ式と同様に変数のキャプチャが行える。
ただ、こちらはC++上で動かなかった。NSからはじまる外部ライブラリがもってこれない(undefined reference to `_NSConcreteStackBlock')というエラーらしいので、Ubuntu上のclangには、アップル社独自拡張のライブラリがディフォルトでは入らないということかもしれない。C++のラムダ式の方が便利で可読性が高いと思うので、clangのコンパイルオプションを眺めた程度で、深追いはせず。
- 参考 Blocksがややこいのでまとめてみる
- clangのコンパイルオプション