关于迭代类型安全枚举的反馈

发布于 2024-09-03 06:54:46 字数 2345 浏览 8 评论 0原文

为了回答之前的问题“Enumerate over an enum in 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;
}

In response to the earlier SO question "Enumerate over an enum in C++", I came up with the following reusable solution that uses type-safe enum idiom. I'm just curious to see the community feedback on my solution. This solution makes use of a static array, which is populated using type-safe enum objects before first use. Iteration over enums is then simply reduced to iteration over the array. I'm aware of the fact that this solution won't work if the enumerators are not strictly increasing.

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人心善变 2024-09-10 06:54:46

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

I haven't looked at the rest of the code, but the "double checked locking" doesn't work -- what if two threads check the flag concurrently while it's still false? You need to use a real lock if you want to support multithreading.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文