2010-10-07 21 views
0

j'ai un ENUM, qui ressemble à ceci:Surcharger opérateur d'incrémentation, en boucle, et les cas bord

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

Je veux surcharger l'opérateur d'incrémentation, donc je peux facilement boucler sur ces quatre mecs.

Lorsque la variable est Clubs, Diamonds ou Hearts, il n'y a aucun problème. C'est la condition de Spades qui me pose un petit problème. Mon premier instinct était de le définir de telle sorte que lorsque la variable est pique, l'incrémentation la définit comme une valeur de Clubs. Le problème est que cela semble rendre impossible de boucler les 4 valeurs dans l'énumération.

Si je fais quelque chose comme

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

alors ma sortie ne va Hearts.

Si je ne

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

alors ma sortie boucles juste pour toujours! Donc, je peux évidemment penser à quelques solutions de contournement pour cela ... Je ne suis pas sûr de ce que fait la chose C++ idiomatique. Dois-je redéfinir l'incrémentation de sorte que la tentative d'incrémentation d'un Spade aboutisse à un Spade? ou peut-être jette une exception?

Pour réitérer: Je peux certainement penser à quelques moyens hacky pour résoudre ce problème. Je veux juste l'aide de programmeurs expérimentés pour me dire ce qu'ils pensent être la façon la plus «normale» de résoudre le problème.

+1

Vous venez de découvrir, vous-même, le besoin de [itérateurs] (http://www.cplusplus.com/reference/std/iterator/), en particulier le [fin] (http: //www.cplusplus .com/reference/stl/vector/end /) partie. –

Répondre

2

Vous pouvez ajouter des valeurs enum pour les conditions de démarrage et de fin, et une alternative à ++ qui ne retourne pas au début.

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

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

Depuis for et while boucles vérifient toujours la condition avant d'exécuter, il n'y a aucun moyen de mettre fin à leur exécution au milieu d'une plage cyclique sans variables supplémentaires ou le contrôle de flux. Une boucle do while fonctionne le mieux dans ce cas.

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

Dans ce cas, vous n'avez pas besoin FirstSuit et AllSuits.

+0

Pourquoi 'operator ++' ne devrait-il jamais retourner AllSuits? Au contraire, ne devrait-il pas lancer lors de l'incrémentation AllSuits? – UncleBens

+0

cette réponse semble avoir le plus de sens pour moi. Je pense que définir l'opérateur + différemment est ce que je vais faire –

+0

@Uncle: OP semblait décrire une opération modulo. Aucune raison qui devrait être invalide. Il ne peut également jamais retourner AllSuits, * et * throw lors de l'incrémentation de cette valeur. – Potatoswatter

0

Peut-être

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

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

Il y a encore quelque chose unidiomatic (je dois savoir que les clubs est le premier costume). Pourquoi ne pas simplement utiliser la conversion implicite en int?

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

Eh bien, je suppose que j'aurais dû le mentionner, mais j'ai aussi un opérateur << surchargé »pour le costume enum. Je suis conscient que tout cela est très compliqué pour quelque chose de si simple, mais je le fais vraiment comme un exercice OO pour moi-même. Donc, la conversion int implicite n'utiliserait pas mon opérateur. De plus, j'ai envisagé d'ajouter un membre à mon énumération, mais je pensais que c'était inélégant. Bien sûr que je peux le faire s'il s'avère que j'en ai besoin. En outre, désolé de la modification, je ne m'attendais pas à "entrer" pour soumettre mon message. Je suis un débutant ici, D –

1

Comme suggéré dans un commentaire, qu'en est tout simplement la définition de votre ENUM:

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

Ensuite, votre boucle devient:

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

Depuis enum désintègrent valeurs dans (non signé) entiers, vous pouvez utiliser moduluo arithmétique, puis renvoyer à un 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: Rendez ceci dans une classe. Avec une classe, vous pouvez également ajouter des méthodes "print" et "input".