枚举类上的运算符+,起始值不为零



我需要对枚举类进行有效的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();
}

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

有没有一些传统的更有效的方法使这更简单?

编辑:顺便说一句,我无法将 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);
}

问题是枚举不是从零开始,这使得计算变得困难。

这是真的 - 所以首先要做的是减去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);
}

最新更新