ネタバレ
[&]{}();
←ラムダ式でした.
はじめに
普段競技プログラミングをしているNafmoというものです.
今回,色んな人のコードを読んで勉強していたときに出会った [&]{}()
の話をまとめて残しておこうと思い記事を書いています.
私と同じような困惑に遭遇する人がいたときのことを考えて,初めてのQiitaをやっていきます.
普段雰囲気でC++を書いているため,間違っている箇所があれば指摘していただけると助かります!
発端
ある方のコードを読んでいるときのツイートが発端でした.
より具体的には
auto x = [&]{
// 何らかの処理
return result; // 計算結果の返却
}();
というコードに出会い,どういう処理をしているのか初見で分からず困った感じでした.
分かったことと分からなかったこと
ラムダ式っぽいので一旦ググって cpprefjp - ラムダ式 を読みました
分かった(調べた)こと
-
[&](){}
の[&]
はラムダ式のキャプチャの指定っぽそう -
[](){}
は引数がない場合[]{}
と省略できる
わからないこと
-
[&](){}
を省略すると[&]{}
とはなるが,[&]{}()
とはならない気がする-
()
がワープしてる?この書き方知らないな...
-
なにこれ!となりました
x = [&]{}();
が示す意味
これを省略しないで書くとこのようになると教えていただきました
auto f = [&](){
// 計算
return res;
};
auto x = f();
つまり, f == [&](){}
と思うとスッキリしそうです.
そこで定義したラムダ式をすぐ呼び出して使い捨てている,というように理解しました.
ラムダ式を名前を付けずに使っているだけでした.分かってしまえば簡単に見えますが,自分の知らない記法があるのか!?と疑ってしまって固まっていたので,大変助かりました.
変数のスコープを縮める
これだけなら記事にまとめないのですが,リーダブルコードの9章に乗っていたのでその情報と合わせてまとめたいと思います.
このコードによって変数のスコープを縮めることができます.
auto x = [&]{
// x を決めるのに使うローカル変数は x を計算し終わったら寿命が尽きる
}();
波括弧でブロックを作るのと同じような効果があると思います.
変数の影響範囲が短いと,同時に考える変数が減るなどしてコードが読みやすくなると思います.そういった効果が期待されますね.
個人的には,波括弧を使うときとの違いは早期リターン(リーダブルコードではガード節と呼ばれているやつ)ができるなどして,分岐を浅くしやすいというところにあるのかな?なんて考えたりしました.
まとめ
-
auto x = [&]{~~~~}();
はラムダ式を即座に実行して,結果をx
に代入するよ! - このコードにはスコープを縮める意味があって,それがリーダブルコードに乗っていたよ
ということになります.ありがとうございました
おわりに
C++,私が知らないだけでいろんな書き方があると思っているのが良くなかったかもしれませんね.
あとVSCodeのintellisense で 代入されてる側が,返り値と同じ型だったところから気づけても良かったのかなと思いました.反省.
中括弧って言い方廃止?されたんですね,JISにはないらしい
参考文献(?)
- リーダブルコード 9章 p.118 JavaScriptで「プライベート変数」を作る
- あぷりしあさん
- みどりむしさん