C++
C++のstd::stringでswitch~case~defaultをやってみる
C++のswitch文は整数型か列挙型でなければ使えない。(比較対象はCはリテラルかenumのみだが、C++はconst修飾していれば変数でも良い)
なのでfloatやdouble、std::stringなど、整数以外の型はまったく受け付けてくれず、こうした型はif~else ifを数珠つなぎにして書くほかない。
しかし2000年代になってから出てきた新しめのコンパイル型言語(GoやRust、SwiftやKotlinなど)は、大抵どんな型でもswitch(match / when)分岐が書けるようになっている。
特に文字列型での比較は頻繁に出てくるので、これができないC++は置いてけぼりを食らっている感じがする。
C++は基本設計が古く(1983年登場)、互換性を保ったまま拡張され続けているのだが、言語根幹の仕様に関わる部分はどうしても拡張が難しいようだ。(なのでCarbonLanguageなどのC++に置き換わることができる新しい言語が開発されてきている)
同じような理由で、Objective-Cのswitch文もNSString型での比較はできない(というか==演算子での比較すらできない)のだが、マクロを使ってswitch~caseライクに書けるようにした方がおられた。
このアイデアを使えば、C++でもstd::stringでswitch分岐が書けるのでは?と思ってやってみた。
かなり自然な感じで書くことができる。
本家のswitch文と違うのは、Caseを関数的に書いてブレースでブロックを作ることが必要なくらいだ。
switchの開き部分がfor文に展開されるので、break文はC++文法そのままのbreakで書けるのもすごい。
Objective-Cのオリジナルでは、Defaultを必ず書いてそこでbreakしないとforが永久ループしてしまうようなので、このC++版ではそこを工夫してみた。
条件式を比較元が空文字列以外にして、変化式で比較元を空文字列にすることで、2周目に突入しないようにしている。
なのでこのSwitch文では空文字列との比較はできない。
空文字列との比較をしたい人は、//#defineのコメントを外して、その下の1行を削除すればできるようになる。(その代わりDefaultとbreakが無いと永久ループしてしまうので注意)
この方法以外にも、std::mapとラムダ式を組み合わせるという手もある。
|