2010-05-31 123 views
0

在回应早前SO问题“Enumerate over an enum in C++”反馈,我想出了一个使用type-safe enum idiom以下重用的解决方案。我只是很好奇看到社区对我的解决方案的反馈。此解决方案使用静态数组,在首次使用之前使用类型安全的枚举对象填充该静态数组。迭代枚举然后简化为对数组的迭代。我意识到,如果统计员没有严格增加,这个解决方案将不起作用。上遍历类型安全的枚举

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

这只是我的看法,但我想利用预处理器的功率(与Boost.Preprocessor库)是较为直观。您可以使用它来生成各种功能(我的个人收藏夹是从/从字符串表示和从整数到整型)。 – 2010-05-31 18:17:36

回答

0

我没有看过的代码的其余部分,但“双重检查锁定”不工作 - 如果两个线程同时检查标志,同时它还是假的?如果你想支持多线程,你需要使用真正的锁。

+0

我认为这是作为一个评论,说如果你需要“确保使用双重检查锁定”。 – 2010-05-31 18:18:48

+0

我认为你是对的:) – Amnon 2010-05-31 18:49:05