7 votes

Mise en œuvre des valeurs d'énumération circulaires

Quel serait le meilleur moyen de mettre en œuvre une énumération avec des valeurs circulaires, et des fonctions appropriées pour passer d'une valeur à une autre?

Par exemple:

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

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

Cependant, je trouve que c'est sujet aux erreurs et généralement illisible. Y a-t-il un moyen plus approprié de traiter ce type d'énumérations?

10voto

Peter K. Points 3837

Vous pourriez toujours faire :

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

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

Exemple d'utilisation / petit test :

#include 

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);
    }
}

Output:

NORTH
WEST
SOUTH
EAST
NORTH
WEST
SOUTH
EAST

Exemple en direct

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X