[英]Overloading cast operator for enum class
在我的項目中,我使用了多個枚舉類,我需要根據需要在何處使用它們輕松地在它們之間進行轉換。 它們基本上描述相同的東西,但命名不同,以使代碼更易於使用。 以下是枚舉類:
enum class tetroType {
None, I, O, T, J, L, S, Z
};
enum class gridBlock {
Empty, Blue, Green, Orange, Purple, Red, Teal, Yellow
};
tetroType 中的每個值都對應於 gridBlock 中的一個值(fe tetroType::I = gridBlock::Teal),但第一個值保存有關 tetronimo 形狀的信息(在 tetronimo 類中),第二個保存有關塊顏色的信息(在網格類)。 我知道我可以只使用一個枚舉,但這樣你就不會丟失任何信息。 如果可能的話,我還需要將其轉換為字符串。 這就是我想使用它的方式:
gridBlock grid = (gridBlock)tetroType::I;
string texture = (string)grid;
現在我設置它的方式是這樣的。 每當我需要將一個枚舉轉換為另一個枚舉或字符串時,我都會在其他方法的中間使用此開關:
switch (type) {
case tetroType::I:
block = gridBlock::Teal;
break;
case tetroType::O:
block = gridBlock::Yellow;
break;
case tetroType::T:
block = gridBlock::Purple;
break;
case tetroType::J:
block = gridBlock::Blue;
break;
case tetroType::L:
block = gridBlock::Orange;
break;
case tetroType::S:
block = gridBlock::Green;
break;
case tetroType::Z:
block = gridBlock::Red;
break;
case tetroType::None:
block = gridBlock::Empty;
}
簡單的回答:不要使用enum class
,而是使用普通enum
,它們可以隱式轉換為它們的基礎類型(默認int
)。
在C ++ 11, enum class
是一種強的別名,其必須從鑄造。
您應該考慮將枚舉類作為整數重載(這是 C++ 11 的特性)。
enum class tetroType : int {
I = 1, O = 2, T = 3, J = 4, L = 5, S = 6, Z = 7, NONE
};
enum class gridBlock : int {
Blue = 1, Green = 2, Orange = 3, Purple = 4, Red = 5, Teal = 6, Yellow = 9, EMPTY
};
從這里您可以使用 ether C Style typecasting 或 static_cast 編寫基本轉換
gridBlock ConvertTetro(tetroType type){
return static_cast<gridBlock>(static_cast<int>(type));
}
gridBlock ConvertTetro(tetroType type){
return (gridBlock)((int)((type)));
}
這將匹配任何網格塊到相等的四元組,如果沒有匹配類型,將默認為 gridBlock::EMPTY。 如果需要,這個函數應該很容易弄清楚如何走另一條路。 從這里開始,您需要匹配兩者之間的 int 值。
您還可以使用 char 值作為字符文字('A'、'b'、'!')使用
enum class enumName : char
只要兩種基礎類型,這就會起作用
如果您接受必須保持兩個枚舉之一的定義與另一個一致的事實,以便每個gridBlock
從tetroType
獲取一個值,那么您可以覆蓋operator==
以在比較中無縫使用它們並覆蓋不同的運算符(例如<<=
) 來模擬不同類型之間的分配。
像這樣的東西:
#include <iostream>
#include <type_traits>
#include <cassert>
using namespace std;
enum class tetroType {
None, I, O, T, J, L, S, Z
};
enum class gridBlock {
Empty = static_cast<std::underlying_type<tetroType>::type>(tetroType::None),
Blue = static_cast<std::underlying_type<tetroType>::type>(tetroType::I),
Green = static_cast<std::underlying_type<tetroType>::type>(tetroType::O),
Orange = static_cast<std::underlying_type<tetroType>::type>(tetroType::T),
Purple = static_cast<std::underlying_type<tetroType>::type>(tetroType::J),
Red = static_cast<std::underlying_type<tetroType>::type>(tetroType::L),
Teal = static_cast<std::underlying_type<tetroType>::type>(tetroType::S),
Yellow = static_cast<std::underlying_type<tetroType>::type>(tetroType::Z)
};
bool operator==(const tetroType& t, const gridBlock& g) { return static_cast<gridBlock>(t) == g; }
bool operator==(const gridBlock& g, const tetroType& t) { return static_cast<gridBlock>(t) == g; }
bool operator!=(const tetroType& t, const gridBlock& g) { return static_cast<gridBlock>(t) != g; }
bool operator!=(const gridBlock& g, const tetroType& t) { return static_cast<gridBlock>(t) != g; }
gridBlock& operator<<=(gridBlock& g, tetroType t) { g = static_cast<gridBlock>(t); return g; }
tetroType& operator<<=(tetroType& t, gridBlock g) { t = static_cast<tetroType>(g); return t; }
int main() {
tetroType t1 = tetroType::I, t2 = tetroType::O;
gridBlock g1 = gridBlock::Blue, g2 = gridBlock::Green;
gridBlock g3;
g3 <<= t1;
tetroType t3;
t3 <<= g2;
assert(t1 == g1);
assert(t1 != g2);
assert(g3 == t1);
assert(t3 == g2);
return 0;
}
雖然這個解決方案很簡潔,但它非常神秘和晦澀,所以你最好清楚地記錄這種行為。 但總的來說,使用enum class
來覆蓋operator<<=
等operator<<=
是非常安全的,因為它們在任何情況下都沒有定義。
請注意,您可以在值之間使用自定義映射,但如果您不需要它們,因為您可以用另一個初始化一個值,則無需手動映射它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.