Visual C++ 2010はenum class
がない(SP1でもC++0xの機能を増やす予定はないとか)。
でも、enum classがなくても型チェックはある程度できる。
enum WeaponType { WEAPON_TYPE_MOCHI, WEAPON_TYPE_SALMIAKKI, }; enum TreatsType { TREATS_TYPE_MOCHI, TREATS_TYPE_SALMIAKKI, }; // the trick is here void operator ==(WeaponType, int); void operator !=(WeaponType, int); void operator ==(int, WeaponType); void operator !=(int, WeaponType); void operator ==(TreatsType, int); void operator !=(TreatsType, int); void operator ==(int, TreatsType); void operator !=(int, TreatsType); void test() { if (WEAPON_TYPE_MOCHI != WEAPON_TYPE_SALMIAKKI) { // ok eat(); } if (WEAPON_TYPE_MOCHI == TREATS_TYPE_SALMIAKKI) { // error! scream(); } }
「enum
は#define
やconst
の羅列より短いから使っているだけなので、自分は使わないだろう」と思っていたが、昨日別種のenum
を比較するコードを書いてバグを出し、30分悩んだ。なので少なくとも型チェックのところは欲しいと思うようになった。
type-safe enumのようなクラスでラップするという方法は確実だが、文字数がとても多いのでそらで書き下せる自信がない。「enum
のまま型チェックをする」方法を考えていたら上記の方法を思いついた。
つまり、「比較のoperatorを
定義して、実装しない」という方法だ。
最初は operator ==(WeaponType, TreatsType);
のように定義していたが、 enum
の数を増やすと爆発することに気づいて int
に変えた。 int
でないほうがエラーは多少読みやすい。
返り値を void
でなく bool
で定義すると、リンク時のエラーになる。 void
で定義するとコンパイル時にエラーが出てくれるのでそうした。