2015-07-06 117 views
2

這與Are C++ enums signed or unsigned?密切相關。根據JavaMan的回答,enum既不是signed也不是unsigned。但它確實遵循整體促銷規則。如何覆蓋枚舉的積分促銷規則?

我與使用enums圖書館工作,然後將其傳遞到預期大多unsigned類型(如unsigned intsize_t)其他類對象。由於語言的規則,啓用-Wsign-conversion警告以努力捕捉合法錯誤導致數量誤報。

規則類創造了一種難以確保類型安全並且能夠捕捉到常見錯誤的情況。這很困難,因爲我想避免像static_cast這樣的東西在整個代碼中灑落。

有沒有辦法改寫enums爲具體的signedunsigned類型的語言默認行爲? (類似於您可以指定char的方式是有符號的還是無符號的)。


相關,該庫是在20世紀90年代編寫的,因此它支持一些較老的編譯器。如果解決方案甚至可以解決C++ 03和更早的問題,那將是非常好的。

How to guard move constructors for C++03 and C++11?,我知道在實踐中沒有可靠的方法來檢測其他C++語言變體何時生效。在使用-std=c++03-std=c++11進行Clang 3.5測試期間,它的表面平坦下來。

+1

你可以使用C++ 11,你可以修改這個庫中的枚舉定義? – Praetorian

+0

@Praetorian - 不幸的是,我們不能依賴C++ 11。我們仍然需要支持C++ 03(也可能更早)。好的一面,我可以修改庫中的枚舉定義。如果需要的話,該圖書館是魏岱的[Crypto ++](http://www.cryptopp.com/)。對不起提早不提供這些信息。 – jww

回答

1

你可以滾你自己enum class

struct safe_enum { 
    enum type { 
     value1, value2, value3 
    }; 
    type value; 

    operator unsigned int() 
     { return value; } 
}; 

safe_enum foo = safe_enum::value1; 
unsigned bar = safe_enum::value2; 

不幸的是,這個失去的C++枚舉03的「無範圍」的行爲,所以這種最佳實踐模式將打破代碼庫。另外,將enum更改爲class會破壞ABI,如果它已作爲DLL提供的話。

2

C++ 03枚舉的基礎類型取決於其枚舉值的範圍,並且它促進其基礎類型,而不是int(C++ 98 [conv.prom]§4.5/ 2)。

強制枚舉表現爲unsigned int的骯髒方法是添加一個值,只有unsigned int可以處理。

enum things { 
    a, b, c, 
    force_unsigned = -1U 
}; 

演示:http://coliru.stacked-crooked.com/a/d3ded108fb5a68bf

+0

不得不撓我的頭什麼「-1u」將導致,這幫助了我:http://brnz.org/hbr/?p=1433 – user2950911

+0

@ user2950911是的,重要的是,'-1u'是一個積極的數。所有的枚舉值都需要積極才能正常工作,否則編譯器將被迫選擇'signed long'或'signed long long',它可以同時擁有'-1u'和正確的負數。 – Potatoswatter