2010年9月30日木曜日

false としか比較できない bool みたいなもの

Twitter やってると全然ブログ更新しなくなってしまいますね。


整数値をキャストするとゼロなら偽、それ以外なら真になる。
でもそんなとき #define TRUE (1) なんかと比較するとゼロでない何らかの数値は
"1"とは限らないので具合が悪い。なので偽を表す定数としか比較できないように
したい。

…というような要件の解決を試みるコード。

#include <boost/static_assert.hpp>

// nil かそれ以外の状態を持つ型
enum flag_t { nil = 0 };

// 以下のオペレーターは実装されない
bool operator ==( flag_t, bool  );
bool operator ==( flag_t, int   );
bool operator ==( flag_t, float );
bool operator !=( flag_t, bool  );
bool operator !=( flag_t, int   );
bool operator !=( flag_t, float );

bool operator ==( bool , flag_t );
bool operator ==( int  , flag_t );
bool operator ==( float, flag_t );
bool operator !=( bool , flag_t );
bool operator !=( int  , flag_t );
bool operator !=( float, flag_t );

// enum のサイズって int と同じだっけ?
BOOST_STATIC_ASSERT( sizeof( flag_t ) >= sizeof( bool  ) );
BOOST_STATIC_ASSERT( sizeof( flag_t ) >= sizeof( int   ) );
BOOST_STATIC_ASSERT( sizeof( flag_t ) >= sizeof( float ) );
void func()
{
  const flag_t flg = someFunc();

  // 真なら通る条件文
  if ( flg ) { /* ... */ }

  // 偽なら通る条件文
  if ( flg == nil ) { /* ... */ }

  // 以下はリンカエラーを起こす
  if ( flg == false ) { /* ... */ }
  if ( flg == 12345 ) { /* ... */ }
  if ( flg == 1.23f ) { /* ... */ }
}