【一人 C++20 Advent Calendar 2019】状態を持たないラムダ式がデフォルト構築可能、代入可能となった【24日目】
一人 C++20 Advent Calendar 2019 24日目の記事になります。
状態を持たないラムダ式がデフォルト構築可能、代入可能となった
状態を持たないラムダ式がデフォルト構築可能、代入可能となりました。
次のようにラムダ式の型からオブジェクトを定義することができます。
#include <iostream> #include <map> int main(){ auto hello_world = [] { std::cout << "hello, world" << std::endl; }; // lambda の型から新しいオブジェクトを生成できる decltype(hello_world) hello_world2{}; hello_world2(); // 状態を持っている(キャプチャしている)場合は生成できない auto hello_world3 = [&] { hello_world(); }; // NG // decltype(hello_world3) hello_world4{}; return 0; } /* output: hello, world */
なるほど? これだけだと何が嬉しいんだと思いますよね。
こういう時に便利
std::map
は第三テンプレート引数に比較型を渡すことができます。
これは通常は関数オブジェクト型を定義し、 operator ()
などで処理を記述する必要がありました。
しかし、ラムダ式がデフォルト構築可能になったことで次のようにテンプレート引数に対して直接処理を記述できるようになります。
#include <iostream> #include <map> int main(){ // std::map は第三テンプレート引数に比較型を渡すことができる // 本来は関数オブジェクトクラスを定義してテンプレート引数に渡す必要があった // これを delctype を経由して直接ラムダ式で処理を記述できるようになった auto data = std::map< int, char, decltype([](auto a, auto b) { return a > b; }) > { { 1, 'A' }, { 11, 'J' }, { 12, 'Q' }, { 13, 'K' } }; for(auto&& [key, value] : data){ std::cout << key << ":" << value << std::endl; } return 0; } /* output: 13:K 12:Q 11:J 1:A */
テンプレート引数に直接式を記述したい!!!!って C++11 の頃からずーーーーーっとやりたいと思っていてそんなことをするライブラリも自前でつくったりしていました。
C++20 だと delctype
+ ラムダ式で直接テンプレート引数に処理を記述できるようになるのでかなりメタプログラミングが捗りそうですね…これだよこれを待っていたんだよ!!!
対応コンパイラ
- GCC 9
- Clang 8.0