10

列挙型をよりタイプセーフにするために、マクロで生成されたオーバーロードされた演算子を使用して、列挙型を同じ型の列挙型以外と比較できないようにしました。

#include <boost/static_assert.hpp>

#define MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, op) \
  template<typename T> \
  inline bool operator op(enumtype lhs, T rhs) \
  { \
    BOOST_STATIC_ASSERT(sizeof(T) == 0); \
    return false; \
  } \
  \
  template<> \
  inline bool operator op(enumtype lhs, enumtype rhs) \
  { \
    return static_cast<int>(lhs) op static_cast<int>(rhs); \
  }

#define MAKE_ENUM_TYPESAFE(enumtype) \
  MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, ==) \
  MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, !=) \
  MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, >) \
  MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, <) \
  MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, >=) \
  MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, <=)

// Sample usage:
enum ColorType { NO_COLOR, RED, BLUE, GREEN };
MAKE_ENUM_TYPESAFE(ColorType)

これは通常、望ましい効果があります。フォームの比較はcolor_variable == RED機能しますが、フォームの比較はBoost.StaticAssertcolor_variable == 1のおかげでコンパイル時エラーを生成します。(これはまともなアプローチですか?)

ただし、私のコンパイラ (CodeGear C++Builder) も、これらのオーバーロードされた演算子を使用して暗黙的boolな変換を実装しようとしています。たとえば、if (color_variable) { ... }に変換されif (operator!=(color_variable, 0)) { ... }て がトリガーされ、BOOST_STATIC_ASSERTコンパイルに失敗しています。

これは私のコンパイラ側の間違った動作であると確信しています (たとえば、Comeau と GCC はそれを行いません)。自分で C++0x ドラフト標準を調べてみましたが、セクション 4.12 の下にある次のステートメントしか見つかりませんでした。

ゼロ値、NULL ポインター値、または NULL メンバー ポインター値は false に変換されます。その他の値は true に変換されます。

「ゼロ値」がどのようにチェックされるかについての詳細なし。

4

1 に答える 1

4

次のようなクラスを使用してみませんか?

template<class Enum>
class ClassEnum
{
public:
  explicit ClassEnum(Enum value) : value(value) {}
  inline bool operator ==(ClassEnum rhs) { return value == rhs.value; }
  inline bool operator !=(ClassEnum rhs) { return value != rhs.value; }
  inline bool operator <=(ClassEnum rhs) { return value <= rhs.value; }
  inline bool operator >=(ClassEnum rhs) { return value >= rhs.value; }
  inline bool operator  <(ClassEnum rhs) { return value < rhs.value; }
  inline bool operator  >(ClassEnum rhs) { return value > rhs.value; }

  // Other  operators...
private:
  Enum value;
}

enum ColorTypeEnum { NO_COLOR, RED, BLUE, GREEN };
typedef ClassEnum<ColorTypeEnum> ColorType;

の bool への暗黙的な変換はありませんClassEnum<ColorTypeEnum>

于 2009-11-03T15:21:35.453 に答える