开发者

C++ implicit conversion to bool

开发者 https://www.devze.com 2022-12-10 22:32 出处:网络
In an effort to make my enums more typesafe, I\'ve been using macro-generated overloaded operators to disallow comparing enums against anything but an identically typed enum:

In an effort to make my enums more typesafe, I've been using macro-generated overloaded operators to disallow comparing enums against anything but an identically typed enum:

#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, GREE开发者_如何学CN };
MAKE_ENUM_TYPESAFE(ColorType)

This generally has the desired effect; comparisons of the form color_variable == RED work, while comparisons of the form color_variable == 1 generate compile-time errors thanks to Boost.StaticAssert. (Is this a decent approach?)

However, my compiler (CodeGear C++Builder) is also trying to use these overloaded operators to implement implicit bool conversions. For example, if (color_variable) { ... } is being translated to if (operator!=(color_variable, 0)) { ... } and is triggering the BOOST_STATIC_ASSERT and failing to compile.

I'm fairly certain that this is incorrect behavior on the part of my compiler (Comeau and GCC don't do it, for example) but was wondering if there are any language lawyers present who could confirm. I tried looking up in the C++0x draft standard myself, but all I could find was the following statement under section 4.12:

A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.

without details as to how "a zero value" is checked for.


Why don't you use a class like following?

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;

There is no implicit conversion to bool for ClassEnum<ColorTypeEnum>.

0

精彩评论

暂无评论...
验证码 换一张
取 消