J'écris du code qui ressemble à ceci:
while(true) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
break; // **HERE, I want to break out of the loop itself**
}
}
Y a-t-il un moyen direct de le faire?
Je sais que je peux utiliser un drapeau et rompre la boucle en mettant une interruption conditionnelle juste après le commutateur. Je veux juste savoir si C ++ a déjà une construction pour cela.
goto
attrayant et, parfois, la seule solution propre. Si vous avez tendance à organiser votre code en petites fonctions qui ne font que quelques lignes et font une seule chose chacune, vous ne rencontrerez jamais ce problème. (Incidemment, votre code sera également plus facile à lire.):)
Réponses:
Prémisse
Le code suivant doit être considéré comme une mauvaise forme, quelle que soit la langue ou la fonctionnalité souhaitée:
Arguments à l'appui
La
while( true )
boucle est de mauvaise forme car elle:while(true)
des boucles qui ne sont pas infinies, nous perdons la capacité de communiquer de manière concise lorsque les boucles n'ont en fait aucune condition de terminaison. (On peut soutenir que cela s'est déjà produit, donc le point est sans objet.)Alternative à "Aller à"
Le code suivant est de meilleure forme:
Avantages
Pas de drapeau. Non
goto
. Pas exception. Facile à changer. Facile à lire. Facile à réparer. En plus le code:Le deuxième point est important. Sans savoir comment fonctionne le code, si quelqu'un m'a demandé de faire en sorte que la boucle principale laisse aux autres threads (ou processus) un peu de temps CPU, deux solutions me viennent à l'esprit:
Option 1
Insérez facilement la pause:
Option 2
Remplacer l'exécution:
Ce code est plus simple (donc plus facile à lire) qu'une boucle avec un embarqué
switch
. LaisValidState
méthode doit uniquement déterminer si la boucle doit continuer. La bête de somme de la méthode doit être abstraite dans laexecute
méthode, ce qui permet aux sous-classes de remplacer le comportement par défaut (une tâche difficile utilisant unswitch
et intégrégoto
).Exemple Python
Comparez la réponse suivante (à une question Python) qui a été publiée sur StackOverflow:
Contre:
Ici, il en
while True
résulte un code trompeur et trop complexe.la source
while(true)
devrait être nuisible me semble bizarre. Il y a des boucles qui vérifient avant de s'exécuter, il y a celles qui vérifient après et il y a celles qui vérifient au milieu. Puisque ces derniers n'ont pas de construction syntaxique en C et C ++, vous devrez utiliserwhile(true)
oufor(;;)
. Si vous considérez que c'est faux, vous n'avez pas encore suffisamment réfléchi aux différents types de boucles.while(true) {string line; std::getline(is,line); if(!is) break; lines.push_back(line);}
bien sûr, je pourrais transformer cela en une boucle préconditionnée (en utilisantstd::getline
comme condition de boucle), mais cela présente des inconvénients en soi (line
devrait être une variable en dehors de la portée de la boucle). Et si je le faisais, je devrais demander: pourquoi avons-nous trois boucles de toute façon? Nous pourrions toujours tout transformer en une boucle préconditionnée. Utilisez ce qui vous convient le mieux. Siwhile(true)
cela vous convient, utilisez-le.Vous pouvez utiliser
goto
.la source
goto
. Le PO est clairement mentionné sans utiliser de drapeaux . Pouvez-vous suggérer une meilleure façon, compte tenu des limites du PO? :)Une autre solution consiste à utiliser le mot-clé
continue
en combinaison avecbreak
, c'est-à-dire:Utilisez l'
continue
instruction pour terminer chaque étiquette de cas où vous voulez que la boucle continue et utilisez l'break
instruction pour terminer les étiquettes de cas qui doivent terminer la boucle.Bien sûr, cette solution ne fonctionne que s'il n'y a pas de code supplémentaire à exécuter après l'instruction switch.
la source
:(
:(
Sinon une implémentation très propre.Une manière élégante de faire ceci serait de mettre ceci dans une fonction:
Facultativement (mais 'mauvaises pratiques'): comme déjà suggéré, vous pouvez utiliser un goto, ou lancer une exception à l'intérieur du commutateur.
la source
AFAIK il n'y a pas de "double break" ou de construction similaire en C ++. Le plus proche serait un
goto
- qui, bien qu'il ait une mauvaise connotation pour son nom, existe dans la langue pour une raison - tant qu'il est utilisé avec prudence et parcimonie, c'est une option viable.la source
Vous pouvez mettre votre commutateur dans une fonction distincte comme celle-ci:
la source
Même si vous n'aimez pas goto, n'utilisez pas d'exception pour quitter une boucle. L'exemple suivant montre à quel point cela pourrait être laid:
J'utiliserais
goto
comme dans cette réponse. Dans ce cas,goto
le code sera plus clair que toute autre option. J'espère que cette question vous sera utile.Mais je pense que l'utilisation
goto
est la seule option ici à cause de la chaînewhile(true)
. Vous devriez envisager de refactoriser votre boucle. Je suppose la solution suivante:Ou même ce qui suit:
la source
goto
, n'utilisez pas d'exception pour quitter une boucle:"?Il n'y a pas de construction C ++ pour sortir de la boucle dans ce cas.
Utilisez un indicateur pour interrompre la boucle ou (le cas échéant) extrayez votre code dans une fonction et utilisez
return
.la source
Vous pourriez potentiellement utiliser goto, mais je préférerais définir un indicateur qui arrête la boucle. Puis sortez de l'interrupteur.
la source
Pourquoi ne pas simplement corriger la condition dans votre boucle while, faisant disparaître le problème?
la source
Non, C ++ n'a pas de construction pour cela, étant donné que le mot-clé "break" est déjà réservé pour quitter le bloc de commutation. Alternativement, un do.. while () avec un drapeau de sortie pourrait suffire.
la source
Je pense;
la source
Le moyen le plus simple de le faire est de mettre un simple IF avant de faire le SWITCH, et ce IF teste votre condition pour sortir de la boucle .......... aussi simple que possible
la source
Le
break
mot clé en C ++ termine uniquement l'itération ou l'switch
instruction englobante la plus imbriquée . Ainsi, vous ne pouviez pas sortir de lawhile (true)
boucle directement dans l'switch
instruction; Cependant, vous pouvez utiliser le code suivant, qui, à mon avis, est un excellent modèle pour ce type de problème:Si vous aviez besoin de faire quelque chose lorsque
msg->state
égal à égalDONE
(comme exécuter une routine de nettoyage), placez ce code immédiatement après lafor
boucle; c'est-à-dire si vous avez actuellement:Utilisez ensuite à la place:
la source
Je suis étonné de voir à quel point c'est simple compte tenu de la profondeur des explications ... Voici tout ce dont vous avez besoin ...
LOL !! Vraiment! C'est tout ce dont vous avez besoin! Une variable supplémentaire!
la source
la source
J'ai eu le même problème et je l'ai résolu à l'aide d'un drapeau.
la source
Si je me souviens bien de la syntaxe C ++, vous pouvez ajouter une étiquette aux
break
instructions, comme pourgoto
. Donc, ce que vous voulez serait facilement écrit:la source
la source