【问题标题】:Two enum with same value, how to access them?两个具有相同值的枚举,如何访问它们?
【发布时间】:2014-04-09 23:17:20
【问题描述】:
class Card
{
public:
    enum class Rank{ TWO = 2, THREE = 3, FOUR = 4, FIVE = 5, SIX = 6, SEVEN = 7, 
                EIGHT = 8, NINE = 9, TEN = 10, JACK = 10, 
                QUEEN = 10, KING = 10, ACE = 11 };
    Rank r;

}

不使用Card::Rank::TEN Card::Rank::JACKCard::Rank::QUEEN Card::Rank::KING是否可以访问TEN、JACK和Queen?

我正在使用switch 重载ostream operator<<,但它有错误... 当我尝试在 Deck 类中创建一个初始化 52 张卡片的构造函数时,我发现这是不可能的。

【问题讨论】:

  • 请显示未编译的部分,否则我们最终可能会帮助您解决错误的问题。
  • 旁注:这是二十一点吗? Ace 也可以是 1。

标签: c++ enums


【解决方案1】:

就必须根据here 的答案之一输入Card::Rank::TEN 而言,您应该可以改用Card::TEN,前提是您像这样声明您的enum

class Card
{
public:
    enum Rank { TWO = 2, THREE = 3, FOUR = 4, FIVE = 5, SIX = 6, SEVEN = 7, 
                EIGHT = 8, NINE = 9, TEN = 10, JACK = 10, 
                QUEEN = 10, KING = 10, ACE = 11 };

无论如何,您都不能在switch 语句中使用两个相同的值。这是因为当代码运行并且您获得值 10 时,您的代码将无法确定它是十、杰克、皇后还是国王。

要么更改值,要么在您的开关中仅使用其中一个。这是一个人为的例子:

int function(int value)
{
    int rv = 0;

    switch (value)
    {
        case 0:
            rv = 7;
            break;
        case 1:
            rv = 8;
            break;
        case 1:
            rv = 21;
            break;
        default:
            rv = 0;
            break;
    }

    return rv;
}

int main()
{
    printf("What does function(1) return? %d", function(1));

    return 0;
}

这是没有意义的,因为我们在传递值1 时返回两个不同的值,因此编译器不允许这样做。

如果你在 switch 中使用 Card::Rank::TENenum 值也是一样的,因为它们的 与编译器不允许的相同。

Card::Rank card = Card::Rank::TEN;

switch(card)
{
    // Some cases...
    case Card::Rank::JACK:
        // Do something
        break;
    case Card::Rank::TEN: // <- not allowed since it is the same as the case for Card::Rank::JACK.
        // Do something else
        break;
    // Some more cases...
}

这是不允许的。以下似乎应该没问题,因为编译器应该能够看到在两种情况下运行的是相同的代码,但它仍然无法工作。

switch(card)
{
    // Some cases...
    case Card::Rank::JACK:
    case Card::Rank::TEN: // <- still not allowed, even though both code paths for case 10 do the same thing...
        // Do something else
        break;
    // Some more cases...
}

很抱歉,我无法对此给出充分的理由,除了标准本身可能不允许这样做以保持一致性。其他人可能能够详细说明这一点。

【讨论】:

    【解决方案2】:

    具有相同值的多个分支的开关是错误的。枚举值只是写整数的一种奇特方式,所以...

    【讨论】:

      【解决方案3】:

      Card::Rank::TENCard::Rank::JACKCard::Rank::QUEENCard::Rank::KING 之间确实没有区别。你无法将它们区分开来。

      就像你写的一样

      #define TEN 10
      #define JACK 10
      #define QUEEN 10
      #define KING 10
      

      然后以编程方式尝试区分它们。但它们包含完全相同的值;它们是无法区分的。

      【讨论】:

        【解决方案4】:

        您可以将枚举视为一种别名机制。所以我们通常用它来代替幻数。

        因此我们不需要写int card1 = 11; 11 是多少?我们知道 JACK,但不知道 11 是什么。

        另一个优点是它限制了可能的值并且不会看到像int card2 = 14;这样的东西

        所以在这个观点上,如果 J、Q 和 K 有相同的值,那就奇怪了,因为他们没有出示同一张牌。如果你想将一张卡片映射到一个值,那么 std::map 是一个不错的选择。

        enum Rank{ TWO , THREE, FOUR, FIVE, SIX , SEVEN, ......};
        
        
        static const std::map<Rank, value> = 
        {
            {TWO, 2}, {THREE,3},......
        };
        

        如果如d_ominic所说,ACE有两个值,也许你想试试std::multimap

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-19
          相关资源
          最近更新 更多