【问题标题】:Implementation of circular enum values循环枚举值的实现
【发布时间】:2013-04-20 20:32:47
【问题描述】:

用循环值实现枚举的最佳方法是什么,以及从一个值转换到另一个值的适当函数?

例如:

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

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

但是,我觉得这很容易出错并且通常不可读。有没有更合适的方法来处理这种类型的枚举?

【问题讨论】:

  • 用四格 switch 语句明确拼写出来?那将是最易读的选项。
  • 如果有更多的值怎么办?
  • 如果您将left 更改为nextCounterclockwise(或者简而言之nextCCW),对我来说更具可读性:-D

标签: c++ c++11 enums


【解决方案1】:

你总是可以这样做的:

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

输出:

北 西方 南 东 北 西方 南 东

Live example

【讨论】:

  • 它甚至不需要额外的元素,只需执行% (std::underlying_type&lt;Directions&gt;::type(WEST) + 1 )。但是,它看起来确实像一个快速修复,不是吗?
  • @Svalorzen :是的,但WEST + 1 并不是真正的人类可读的。如果在WEST 之后添加了一些东西会发生什么?至少NUMBER_OF_DIRECTIONS 的意图很明确。
  • @PeterK。不过,您还需要将整个 underlying_type 到 NUMBER_OF_DIRECTIONS 都写完,所以它会变得很长 - 而且也不那么可读。
  • 好招!它增加了函数的可读性,但降低了枚举的可读性。
  • @PeterK。这个实现怎么样?加号可能会溢出,但我认为这不太可能(整体促销)。
猜你喜欢
  • 1970-01-01
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-11
相关资源
最近更新 更多