2013-04-20 66 views
6

用循環值實現枚舉的最佳方法是什麼,以及從一個值過渡到另一個值的適當函數是什麼?循環枚舉值的實現

例如:

enum class Direction { 
    NORTH, EAST, SOUTH, WEST 
}; 

constexpr Direction left(Direction d) { 
    return (Direction)((std::underlying_type<Directions>::type(d) - 1) % 4); 
} 

不過,我覺得這是很容易出錯,一般無法讀取。有沒有更適當的方法來處理這種類型的枚舉?

+0

有四拼出來明確案例切換聲明?這將是最可讀的選項。 – RichieHindle 2013-04-20 20:38:50

+0

如果有更多的LOTS值,該怎麼辦? – Svalorzen 2013-04-20 20:39:41

+0

如果將'left'改爲'nextCounterclockwise'(或簡稱爲'nextCCW'),對於我來說更具可讀性:-D – deepmax 2013-04-20 20:50:51

回答

9

你總是可以這樣做:

enum class Direction { 
    NORTH, EAST, SOUTH, WEST, NUMBER_OF_DIRECTIONS 
}; 

constexpr Direction left(Direction d) { 
    using ut = std::underlying_type<Direction>::type; 
    return (Direction)((ut(d) + ut(Direction::NUMBER_OF_DIRECTIONS)-1) 
         % ut(Direction::NUMBER_OF_DIRECTIONS)); 
} 

用法示例/小測試:

#include <iostream> 

std::ostream& operator<<(std::ostream& os, Direction d) 
{ 
    switch(d) 
    { 
     case Direction::NORTH: return os << "NORTH"; 
     case Direction::EAST : return os << "EAST"; 
     case Direction::SOUTH: return os << "SOUTH"; 
     case Direction::WEST : return os << "WEST"; 
     default    : return os << "invalid"; 
    } 
} 

int main() 
{ 
    Direction d = Direction::NORTH; 
    for(int i = 0; i < 2*(int)Direction::NUMBER_OF_DIRECTIONS; ++i) 
    { 
     std::cout << d << "\n"; 
     d = left(d); 
    } 
} 

輸出:

 
NORTH 
WEST 
SOUTH 
EAST 
NORTH 
WEST 
SOUTH 
EAST 

Live example

+0

它甚至不需要額外的元素,只要'%(std :: underlying_type ::類型(WEST)+ 1)'。但是,它確實看起來像是一個快速修復,不是嗎? – Svalorzen 2013-04-20 20:43:11

+1

@Svalorzen:是的,但是'WEST + 1'不是真正的人類可讀的。如果在WEST之後添加了什麼會發生什麼?至少在NUMBER_OF_DIRECTIONS的意圖是明確的。 – 2013-04-20 20:45:15

+0

@PeterK。儘管如此,您還需要將整個'underlying_type'設置爲'NUMBER_OF_DIRECTIONS',所以它會變得很長 - 而且也不可讀。 – Svalorzen 2013-04-20 20:47:44