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

4 ~ 명시 적으로 그것을 밖으로 철자를 case switch 문? 그것은 가장 가독성이 높은 옵션입니다. – RichieHindle

+0

LOTS 값이 더 많으면 어떻게 될까요? – Svalorzen

+0

'left'를'nextCounterclockwise' (또는 간단히'nextCCW')로 변경하면 더 쉽게 읽을 수 있습니다 :-D – deepmax

답변

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

+1

@Svalorzen : 그래,하지만'WEST + 1'은 인간이 읽을 수있는 게 아니야. 'WEST' 이후에 뭔가가 추가되면 어떻게 될까요? 적어도'NUMBER_OF_DIRECTIONS'의 의도로 명확합니다. –

+0

@ Peteter. 여전히'underlying_type' 전체를'NUMBER_OF_DIRECTIONS'로 할 필요가 있습니다. 그래서 꽤 길어질 수 있습니다. – Svalorzen