重载增量运算符、循环和边缘情况

发布于 2024-09-26 12:28:08 字数 686 浏览 2 评论 0原文

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

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

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

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

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

如果我做了类似的事情

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

,那么我的输出只会流向红心。

如果我

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

这样做,那么我的输出就会永远循环!

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

我是否应该重新定义增量,以便尝试增加 Spade 会得到 Spade?或者可能会抛出异常?

重申一下:我绝对可以想出一些古怪的方法来解决这个问题。我只是希望有经验的程序员的指导告诉我他们认为解决问题的最“正常”方法是什么。

I have an enum, that looks like this:

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

I want to overload the increment operator, so I can easily loop over these four dudes.

When the variable is Clubs, Diamonds, or Hearts there no issue. Its the Spades condition that is giving me a little trouble.

My first instinct was to define it so that when the variable is spades, incrementation sets it equal to Clubs. The problem is that this seems to make it impossible to loop over the 4 values in the enum.

If I do something like

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

then my output only goes to Hearts.

If i do

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

then my output just loops forever!

So, I can obviously think of a few workarounds for this... I'm just not sure what the idiomatic C++ thing do to.

Should I redefine incrementation so that attempting to increment a Spade results in a Spade? or maybe throws an exception?

To reiterate: I can definitely think of a few hacky ways to fix this issue. I just want the guidance of experienced programmers to tell me what they think would be the most "normal" way to solve the problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冷情妓 2024-10-03 12:28:08

您可以为开始和终止条件添加 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

You could add enum values for start and termination conditions, and an alternative to ++ which doesn't cycle back to the beginning.

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

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

Since for and while loops always check the condition before executing, there is no way to end their execution in the middle of a cyclic range without additional variables or flow control. A do while loop works best in this case.

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

In this case, you don't need FirstSuit and AllSuits.

无法言说的痛 2024-10-03 12:28:08

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

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

然后您的循环将变为:

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

As suggested in a comment, what about just defining your enum as:

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

Then your loop becomes:

for(Suit i=Clubs;i<EndSuit;++i)
{
    cout<<i<<endl;
}
月亮坠入山谷 2024-10-03 12:28:08

也许

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)

Perhaps

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

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

There's still something unidiomatic (I have to know that Clubs is the first suit).

Why not just use the implicit conversion to int?

for (int i = 0; i < NumberOfSuits; ++i)
慢慢从新开始 2024-10-03 12:28:08

由于enum值衰减为(无符号)整数,您可以使用moduluo算术,然后转换回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.
}

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

Since enum values decay into (unsigned) integers, you could use moduluo arithmetic and then cast back to an 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.
}

Suggestion: Make this into a class. With a class you can also add "print" and "input" methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文