| 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とラムダ式を組み合わせるという手もある。
 
 |