【问题标题】:Overloading increment operator, looping, and edge cases重载增量运算符、循环和边缘情况
【发布时间】:2010-10-07 16:42:08
【问题描述】:

我有一个枚举,看起来像这样:

enum Suit {Clubs, Diamonds, Hearts, Spades};

我想重载增量运算符,这样我就可以轻松地循环这四个家伙。

当变量是梅花、方块或红心时,没有问题。黑桃条件给我带来了一些麻烦。

我的第一个直觉是定义它,以便当变量是黑桃时,增量设置它等于梅花。问题是这似乎使得遍历枚举中的 4 个值成为不可能。

如果我这样做

for(Suit i=Clubs;i<Spades;++i)
     {cout<<i<<endl;}

那么我的输出只会发送到 Hearts。

如果我愿意

for(suit i=Clubs;i<=Spades;++i)
    {cout<<i<<endl;}

然后我的输出将永远循环!

所以,我显然可以想到一些解决方法...我只是不确定惯用的 C++ 的作用是什么。

我是否应该重新定义增量,以便尝试增加 Spade 会导致 Spade?或者可能引发异常?

重申:我绝对可以想出一些解决此问题的技巧。我只是希望有经验的程序员的指导告诉我他们认为最“正常”的解决问题的方法。

【问题讨论】:

  • 您自己发现了iterators 的需求,尤其是end 部分。

标签: c++ operator-overloading for-loop


【解决方案1】:

您可以为开始和终止条件添加enum 值,以及++ 的替代项,它不会循环回到开头。

enum Suit { FirstSuit, Clubs = FirstSuit, Diamonds, Hearts, Spades, AllSuits };

for ( suit i = FirstSuit; i != AllSuits; i = iterate_suits( i ) )

由于forwhile 循环总是在执行前检查条件,如果没有额外的变量或流控制,就无法在循环范围的中间结束它们的执行。在这种情况下,do while 循环效果最好。

Suit iter_suit = my_suit; // iterate over all suits beginning with my_suit.
do {
} while ( ++ iter_suit != my_suit );

在这种情况下,您不需要FirstSuitAllSuits

【讨论】:

  • 为什么operator++ 永远不会返回 AllSuits?相反,它不应该在增加 AllSuits 时抛出吗?
  • 这个答案对我来说似乎最有意义。我认为以不同的方式定义 operator+ 是我要做的事情
  • @Uncle:OP 似乎在描述模运算。没有理由应该是无效的。它也永远不会返回 AllSuits,在增加该值时抛出。
  • @Alexander:发布后我突然想到operator+ 的重载需要添加AllSuits 才能获得有效的返回值。那么你不妨只使用AllSuits(或NumberOfSuits,或其他)作为常量。
  • 我不明白的是,如果 i 始终具有 4 个较小值之一,那么 ` i i <= Spades 永不终止循环有何不同?或者你是否也建议给operator&lt; 赋予不寻常的语义? :)
【解决方案2】:

正如评论中所建议的,将您的枚举定义为:

enum Suit {Clubs, Diamonds, Hearts, Spades, EndSuit};

那么你的循环就变成了:

for(Suit i=Clubs;i<EndSuit;++i)
{
    cout<<i<<endl;
}

【讨论】:

    【解决方案3】:

    也许

    enum Suit {Clubs, Diamonds, Hearts, Spades, NumberOfSuits};
    
    for(Suit i=Clubs;i<NumberOfSuits;++i)
     {cout<<i<<endl;}
    

    还有一些不习惯的东西(我必须知道俱乐部是第一花色)。

    为什么不直接使用到 int 的隐式转换?

    for (int i = 0; i < NumberOfSuits; ++i)
    

    【讨论】:

    • 好吧,我想我应该提到这一点,但我也有一个用于西装枚举的重载
    【解决方案4】:

    由于 enum 值衰减为 (unsigned) 整数,您可以使用 模数 算术,然后再转换回 enum

    enum Suite add(const enum Suite card1, const enum Suite card 2)
    {
     unsigned int result = card1;
     result += card2;
     result = result % 4;
     return (enum Suite) result;  // Casting shown for readability.
    }
    

    建议:把它变成一个类。通过类,您还可以添加“打印”和“输入”方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多