【问题标题】:operator+ on enum class with non zero starting value具有非零起始值的枚举类上的运算符+
【发布时间】:2020-01-02 10:28:15
【问题描述】:

我需要高效的operator+ 用于枚举类,问题是枚举不是从零开始计算困难。

这里是有问题的枚举:

#include <cstdint>
#include <iostream>

enum class CardRank : std::uint16_t
{
    Two = 2,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Jack,
    Queen,
    King,
    Ace     // = 14
};

我希望此枚举的 operator+ 接受任何整数值(最多 short 的限制)。

经过一段时间的努力,我得出了以下算法:

inline CardRank operator+(const CardRank& rank, const std::uint16_t num)
{
    std::uint16_t need = static_cast<std::uint16_t>(rank) + num;

    if (need < 15)
        return static_cast<CardRank>(need);

    std::uint16_t result = need % 14 + need / 14;

    return static_cast<CardRank>(result > 14 ? result - 13 : result);
}

这里是测试代码:

int main()
{
    CardRank rank = CardRank::King;

    // = CardRank::Ace
    std::cout << static_cast<std::uint16_t>(rank + 1) << std::endl;

    // = CardRank::Four
    std::cout << static_cast<std::uint16_t>(rank + 17) << std::endl;

    // = CardRank::Two
    std::cout << static_cast<std::uint16_t>(rank + 41) << std::endl;

    // = CardRank::Ten
    std::cout << static_cast<std::uint16_t>(rank + 114) << std::endl;

    std::cin.get();
}

计算是正确的,运算符工作正常,但问题是我只想将两个数字相加, 但事实证明,获得结果所需的计算量不值得拥有运算符。

有没有一些传统的更有效的方法可以让这更简单?

编辑: 顺便说一句,我不能将 Ace 添加到开头并将其设置为 1,因为排序算法从最高到最小卡排序。意思是 ace 必须在国王之上。

编辑

感谢答案,我得到了以下一个班轮:

inline CardRank operator+(const CardRank& rank, const std::uint16_t num)
{
    constexpr std::uint16_t offset = 2;
    constexpr std::uint16_t cards = 13;

    return static_cast<CardRank>((static_cast<std::uint16_t>(rank) - offset + num) % cards + offset);
}

【问题讨论】:

  • need / 14 in operator+ 是什么意思?如我所见,这意味着几乎“const std::uint16_t num 比最大可能值大多少倍?
  • need % 14 是在 0 处获取起始值(不存在),need / 14 告诉该起始值被命中了多少次。这就是您知道结果必须增加多少的方式。

标签: c++ enums operator-overloading


【解决方案1】:

问题是枚举不是从零开始计算困难。

这是真的——所以首先要做的是减去 2,使其从 0 开始。记得在最后加上 2。这样就很简单了。

inline CardRank operator+(const CardRank& rank, const std::uint16_t num)
{
    std::uint16_t need = (static_cast<std::uint16_t>(rank) - 2 + num) % 13 + 2;

    return static_cast<CardRank>(need);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多