10
votes

Comment "casser" «sortir» d'une fonction?

Compte tenu d'une fonction qui renvoie une valeur, est-il possible de quitter la fonction donnée à une certaine condition sans rien renvoyer? Si oui, comment pouvez-vous accomplir cela?

Exemple: xxx

alors dites que vous êtes dans cette fonction. Existe-t-il un moyen de la sortir sans rien faire?

c++

2 commentaires

Cela pourrait vous aider si vous expliquez pourquoi vous voulez faire cela, nous pouvons être certains que nous vous conseillons correctement.


@Tom: C'est une question simplifiée, mais j'essaie de mettre en œuvre une fonction d'obtention d'une file d'attente qui "ne rien faire" si la file d'attente est vide.


13 Réponses :


0
votes

en C ++ Une fonction doit renvoyer une valeur (type de valeur, référence ou adresse) si on est spécifié dans la déclaration / définition de la fonction.


0 commentaires

1
votes

Vous pouvez lancer une exception spécifiée et l'attraper en conséquence.


0 commentaires

0
votes

Vous pouvez lancer un exception . Vous ne retourneriez rien, mais vous devrez attraper l'exception pour déterminer quoi faire ensuite (vous pouvez toujours avaler l'exception et ne rien faire pour atteindre ce que vous voulez).


0 commentaires

18
votes

Vous avez deux options: retour code> quelque chose ou lancer code> .

int maint(int argc, char ** argc)
{
     try
     {
           getNumber();
     }
     catch(string std)
     {
          //Your code will execute here if you throw
     }
 }


4 commentaires

Utilisez uniquement l'alternative au lancer si le retour aucune valeur n'est une erreur. C'est difficile à analyser le code qui utilise des exceptions d'exception pour un flux de code normal.


Et, au fait, des exceptions sont assez chères en C ++: le bloc d'essai et le lancer sont coûteux et ne doivent être utilisés que pour des erreurs (c'est-à-dire dans des scénarios exceptionnels exceptionnels).


Pas vraiment vrai sur la partie "coûteuse" (selon le temps d'exécution), mais oui, des exceptions sont destinées aux conditions exceptionnelles (et erronées), pas comme un flux de contrôle alternatif.


@DevSolar: Ils ne sont pas chers en termes de temps de fonctionnement dans le cas non exceptionnel, mais ils sont coûteux en termes de taille de code.



0
votes

Une refonte de votre méthode est probable dans l'ordre si vous devez sortir d'une fonction destinée à renvoyer une valeur ... ou que vous pourriez simplement renvoyer une valeur "Erreur" de quelque sorte.


0 commentaires

17
votes

vous pourrait vous échapper avec un retour; sans valeur de retour. Le compilateur mettra en garde, mais peut ne pas erreur.

mais , pourquoi sur Terre voudriez-vous même considérer cela cela? Qu'est-ce que vous essayez d'atteindre?

et que ressemble au code d'appel? Si c'est int sinvar = getnumber (); alors la valeur de quelque part est indéfinie (qui est une mauvaise chose).

Cela me semble que vous voulez retourner deux pièces d'informations, dont l'un dit si l'autre est valide.

Essayez quelque chose comme xxx


2 commentaires

La norme ne nécessite jamais d'erreur, simplement un "diagnostic". Il traite donc des avertissements et des EWOrs de manière égale. Mais ne laissez pas cela vous tromper: omettre une valeur de retour est une erreur.


+1 Dans mon livre, Tous les avertissements sont des erreurs. Je ne les tolère pas. Et ce serait vraiment flagrante.



0
votes

Quel est votre cas d'utilisation réelle?

Si vous n'avez vraiment besoin de rien retourner et mettre fin à l'exécution de la fonction normale, vous pouvez lancer un Exception .

Vous pouvez également retourner quelque chose que l'appelant interprète comme une erreur (ou «rien de retourné»).

Quelle que soit votre solution, l'appelant doit gérer le cas «rien de retourné» séparément, par ex. Attrapez l'exception ou vérifiez la valeur renvoyée.


0 commentaires

3
votes

alternative des exceptions est le retour du code d'état: xxx


0 commentaires

-1
votes

Vous pouvez utiliser SETJMP / LONDJMP (voir http://fr.wikipedia.org/wiki /Setjmp.h ), mais à partir d'une perspective d'ingénierie logicielle, vous ferez mieux d'utiliser des exceptions ou des codes d'erreur comme mentionné par d'autres personnes ici.


0 commentaires

3
votes

Pour flotter et doubler, il y a une alternative mais pas pour les types INT.

#include <limits>

double Get()
{
  // no valid return value
  return std::numeric_limits<double>::quiet_NaN();
}

double val = Get();
if(val != val) {
  // Retrieved no valid return value 
}
else {
  // No NaN retrieved
}


2 commentaires

Je ne suis pas d'accord, Nan est un float comme n'importe quel autre (dans ce contexte). La valeur de tout ce qu'il revient peut déjà être nan. Je préférerais toujours ajouter un paramètre Bool Out supplémentaire que d'ajouter une hypothèse au contrat entre l'appelant et la callee.


Cela peut être vrai ou non, mais je pense que s'il y a une nan utilisée, vous devez en être conscient. Nan n'est pas comme un autre nombre car toutes les conditions seront vraies. (Nan> 1 && nan <1 && nan == 1) sera évalué à vrai.



1
votes

Vous pouvez également retourner une classe / structure avec une certaine conversion magique utile pour votre besoin spécial.

Exemple de vie réelle: Une fois que j'avais réellement retourner deux informations de la même valeur de retour, une valeur à Rapport Si un message de fenêtre avait été complètement traité et que la valeur à renvoyer si le traitement était déjà terminé. Donc, j'ai tout emballé dans une classe comme celle-ci: xxx

Cela m'a permis de faire juste renvoyer false; dans une fonction qui a renvoyé une messagerieValue à la messagerie Le message devait encore être traité, ou à Retour TRUE / 15 / PLUS; Si le message avait été complètement traité et que j'ai déjà eu une valeur de retour. L'appelant, de son côté, pourrait simplement faire xxx

si vous avez des besoins plus compliqués, vous pouvez également envisager d'utiliser Boost :: Tuple.


0 commentaires

8
votes

Solution simple: xxx


5 commentaires

Vous devez retourner quelque chose, même s'il s'agit simplement d'un objet "vide" en option . Ne pas retourner quelque chose provoque un comportement indéfini pour toutes les fonctions autres que les principales et ceux qui renvoient nul.


Est-ce un comportement indéfini ou un objet construit par défaut (non défini pour les bâtiments / pods)? Quoi qu'il en soit +1 pour suggérer boost :: facultatif , c'est la voie avec des valeurs facultatives ...


@sellibitze: bien sûr pour ce code "rien" signifie boost :: optionnel () . Voir le commentaire ci-joint: "Implémentez une fonction d'accès à une file d'attente qui ne fera rien si la file d'attente est vide".


Il est incroyable: quelle que soit la classe de services publics que vous puissiez penser, c'est déjà là-bas à Boost et c'est mieux que toute classe de ce genre que vous auriez pu écrire (il est plus générique / rangé / raii / interagit mieux avec le STD LIB et Stimuler / .. .).


Bonus: The Docs of Boost :: optionnel Discutez déjà des différentes approches de ce problème dont nous parlons ici. Ainsi, boostez non seulement un code prêt à l'emploi, mais également des discussions sur les forums. Un peu effrayant, si vous y pensez.



3
votes

Il est nécessaire que l'utilisateur vérifie d'abord que la file d'attente n'est pas vide (fournissez des moyens pour cela).

alors vous pouvez:

  • Ne vérifiez rien et invoquez simplement un comportement indéfini (accéder à des données sous-jacentes comme si c'était là) - c'est la faute de l'utilisateur
  • Vérifiez et lancez une exception
  • Assert (le résultat est indéfini avec NDEBUG)

    Vérification, puis invoquant un comportement non défini (retourner une valeur arbitraire) est la pire chose à faire. Vous obtenez les deux frais d'exécution du chèque et l'appelant n'est pas plus sage, car le résultat n'est toujours pas défini.


1 commentaires

Ceci est un peu problématique dans les environnements multi-filetés, en particulier si plusieurs threads sont en lecture.