2013-04-20 77 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