0

为响应较早的 SO 问题“在 C++ 中枚举枚举”,我提出了以下使用类型安全枚举惯用语的可重用解决方案。我只是想看看社区对我的解决方案的反馈。此解决方案使用静态数组,该数组在首次使用前使用类型安全的枚举对象填充。然后简单地将枚举迭代简化为数组迭代。我知道如果枚举数没有严格增加,这个解决方案将不起作用。

template<typename def, typename inner = typename def::type>
class safe_enum : public def
{
  typedef typename def::type type;
  inner val;

  static safe_enum array[def::end - def::begin];
  static bool init;

  static void initialize()
  {
    if(!init) // use double checked locking in case of multi-threading.
    {
      unsigned int size = def::end - def::begin;
      for(unsigned int i = 0, j = def::begin; i < size; ++i, ++j)
        array[i] = static_cast<typename def::type>(j);
      init = true;
    }
  }

public:

  safe_enum(type v = def::begin) : val(v) {}
  inner underlying() const { return val; }

  static safe_enum * begin()
  {
    initialize();
    return array;
  }

  static safe_enum * end()
  {
    initialize();
    return array + (def::end - def::begin);
  }

  bool operator == (const safe_enum & s) const { return this->val == s.val; }
  bool operator != (const safe_enum & s) const { return this->val != s.val; }
  bool operator <  (const safe_enum & s) const { return this->val <  s.val; }
  bool operator <= (const safe_enum & s) const { return this->val <= s.val; }
  bool operator >  (const safe_enum & s) const { return this->val >  s.val; }
  bool operator >= (const safe_enum & s) const { return this->val >= s.val; }
};

template <typename def, typename inner>
safe_enum<def, inner> safe_enum<def, inner>::array[def::end - def::begin];

template <typename def, typename inner>
bool safe_enum<def, inner>::init = false;

struct color_def
{
  enum type
  {
      begin, red = begin, green, blue, end
  };
};

typedef safe_enum<color_def> color;

template <class Enum>
void f(Enum e)
{
  std::cout << static_cast<unsigned>(e.underlying()) << std::endl;
}

int main()
{
  std::for_each(color::begin(), color::end(), &f<color>);
  color c = color::red;
}
4

1 回答 1

0

我还没有查看其余的代码,但是“双重检查锁定”不起作用——如果两个线程同时检查标志而它仍然为假怎么办?如果要支持多线程,则需要使用真正的锁。

于 2010-05-31T18:15:25.657 回答