Sans entrer dans les exceptions générales VS Codes d'erreur Discussion, que pensez-vous sont les inconvénients de l'utilisation de Cette approche présente évidemment l'avantage de ne pas avoir à utiliser des paramètres pour la valeur de retour de la fonction ou le code d'erreur (en fonction de la manière dont vous le préférez). P> std :: paire code> ou
std: tuple code> pour renvoyer plusieurs valeurs, à savoir la valeur de retour de la fonction et le code d'erreur / de réussite, similaire au nombre de Go Les développeurs font apparemment la manutention d'erreurs ? P>
4 Réponses :
Cet indice "idiom" est bon car le type et l'indicateur de succès sont des valeurs de retour de la fonction. L'échec peut ne pas être exceptionnel, alors les exceptions sont parfois inappropriées.
L'inconvénient est cependant que vous devez diviser les deux types de retour. Cela peut être moche; Utilisation de std :: cravate code> aide mais vous ne pouvez pas construire à partir de plusieurs retours. P>
bool success;
std::string value;
std::tie(success, value)=try_my_func();
Convenu que la gestion du retour est difficile à manier. Une alternative est résultat automatique = try_my_func (); if (résultat.first) {std :: string & valeur = résultat.seconde; ...} code>, et c'est un peu plus naturel dans certaines circonstances.
@Stevejessop Oui, en utilisant Auto aide un peu, mais je trouve la prise de référence très "bruyante", espérons pouvoir construire à partir d'un tuple sera ajouté à la langue un jour.
En pratique, je pourrais ne pas vous embêter avec la référence si la valeur n'est utilisée que plusieurs fois dans le code suivant. Il suffit d'écrire résultat.second code> quelques fois: c'est ennuyeux mais pas assez ennuyeux pour faire quoi que ce soit à ce sujet :-)
@ 111111, je suppose que vous pouvez le faire avec une macro, quelque chose comme #define déclend_tie (x, y, expr) résultat automatique = expr; auto & x = résultat.first; AUTO & Y = RÉSULTAT.SECOND CODE> SAUF Bien sûr, vous voudrez utiliser une sorte de gensym pour
résultat code> (
concat (résultat __, __ ligne __) code>, par exemple)
@ici vous pourriez, je ne suis pas sûr de pouvoir m'apporter à utiliser une macro où lorsque une petite verbosité est requise, elle n'élimine toujours pas la construction par défaut.
@ 111111, pensez simplement à la macro comme une implémentation de modèle primitive :) et utilisez des macros simples et des modèles complexes. Vous avez raison sur la construction par défaut, qui est un argument en faveur de toujours concevoir des classes avec un constructeur par défaut vraiment bon marché. Cela doit être un principe de conception quelque part; Vous semblez toujours travailler autour d'une fonctionnalité de bibliothèque ou d'une autre lorsque vous essayez d'éviter la construction par défaut. Fwiw. (J'aimerais aussi voir la caractéristique linguistique, à la manière: a-t-elle été proposée?)
@ici n'est pas sûr, à moins qu'elles ajoutent que la macro, il faudrait être une caractéristique linguistique et "ils" semblent très réticents à le faire. Ce n'est pas la fin du monde, je serais bien loin d'être concentré sur des choses importantes comme le vrai soutien de l'UTF8.
Cela a depuis été ajouté en tant que caractéristique linguistique: en.cppreference.com/w/cpp/ Langue / structuré_binding par exemple Auto [Succès, valeur] = try_my_func () code>
À cette fin, dans la plupart des cas, j'utilise un propre type d'emballage qui introduit un sucre syntaxique. Voyons un exemple: puis, utilisez simplement cette classe comme valeur de retour dans vos méthodes pouvant renvoyer des erreurs: p> de Bien sûr, cette mise en œuvre de la fonction factorielle est horrible, mais démontre la conversion sans gêner le type de retour étendu à l'erreur. p> Exemple d'utilisation: P> Result<int> fac(int n) {
if(n < 0)
return Result<int>::error("n has to be greater or equal zero!");
if(n == 0)
return 1;
if(n > 0) {
Result<int> r = fac(n - 1);
if(r.isError()) return r; // propagate error (similar to exceptions)
return n * r; // r gets automatically converted to int
}
}
v code> doit encore être construit (un inconvénient majeur à des multi-retours), en utilisant quelque chose comme
std :: aligné_storage code> et le remplacement newing serait un meilleur pari, ou simplement utiliser < Code> Boost.Optional code> qui le fait déjà et que le message d'erreur semble repousser les limites dans un territoire d'exception.
Parfois, je ne veux pas utiliser boost. Et parfois (sinon 99% des cas), l'inconvénient de la performance n'a pas d'importance. Cependant, merci d'avoir mentionné cela.
C'est mieux que les codes d'erreur ordinaires car vous n'avez pas à perdre votre vie avec des paramètres. Mais il conserve toujours tous les inconvénients très graves. P>
Vraiment, c'est juste un micro changement, c'est toujours des codes d'erreur - il n'y a pas d'avantage significatif. P>
en utilisant E.G. Boost :: Facultatif Code> Permet à une fonction de "aucun résultat produit" dans le cadre de son contrat d'invocation normal, tout en conservant la sécurité des exceptions. L'utilisation d'un rendement normal également pour le cas «sans résultat produit» peut être important pour la clarté du code d'appel. Mais cela dépend ...
Pour ceux qui ne veulent pas ajouter une dépendance à boost: facultatif code> est trivial pour mettre en œuvre pour le type de pod, et pour la non-POD, on peut simplement utiliser un seul élément
std :: vecteur code> pour transférer la valeur possible. Dans le cas d'aucune valeur que le vecteur est simplement vide (le fait essentiellement de cette façon, on évite une dépendance et obtient un code simple au prix d'une éventuelle allocation dynamique).
"Que pensez-vous sont les inconvénients de l'utilisation de STD: paire ou STD: tuple pour renvoyer plusieurs valeurs, à savoir la valeur de retour de la fonction et le code d'erreur / de réussite" p> blockQuote>
L'opportunité principale de cette approche simpliste (niveau C) en matière de manipulation de défaillance est un p>
- Perte de sécurité. LI> ul>
I.e. Il y a plus qui peut aller mal em>, comme l'accès à une valeur de résultat indéterminé. Ou simplement utiliser une valeur de retour lorsque la fonction n'a pas produit de significatif. P>
L'Old Barton & Nackman
Fachow Code> Strong> La classe a résolu ce problème de sécurité en limitant l'accès à la valeur de résultat. Essentiellement, le code d'appel doit vérifier s'il y a est em> une valeur de résultat, avant de l'utiliser et l'utilisation d'une valeur de résultat logiquement inexistante entraîne une exception ou une terminaison. Le
boost :: facultatif code> strong> classe la même chose. P>
Si vous ne voulez pas une dépendance sur Boost, une classe code> en option (code> en option est triviale à la mise en œuvre pour le type de résultat de la POD et à un coût d'une petite inefficacité possible (allocation dynamique), vous pouvez simplement Utilisez un
std :: vecteur code> pour porter un résultat possible non-pod. P>
Le défi consiste à conserver la clarté du code d'appel, qui est tout le point de l'exercice ... p>
@Anonymous Downvoter: S'il vous plaît faire Expliquer B> Votre Downvote. Le vote n'est pas un bon moyen d'exprimer son désaccord depuis peu ou personne ne peut lire votre esprit et votre faim ce qui a déclenché votre réaction. Quelle aperçu avez-vous eu? Ou quelles connaissances possédez-vous que vous avez choisi de ne pas partager? Ou, alternativement, et beaucoup plus probablement, qu'avez-vous pas compris? Sans explication, les lecteurs ne peuvent pas savoir. La seule chose qu'ils savent, c'est que vous n'étiez pas capable de communiquer ou de partager.
Découvrez l'Old Barton / Nackman
Fabble CODE> B> classe ou plus de version moderne comme Boost
en option code> b>
@ Votes clés: Veuillez ne voter que pour fermer les questions que vous comprenez. Ne voterez pas pour fermer simplement parce que vous omettre de comprendre B> la question. L'incapacité de comprendre ne signifie pas que vous êtes compétent pour voter dessus: cela signifie que cela signifie le contraire
FAIT FUN - Les questions les plus utilisables, riches et éduquées sur CO sont fermées, "non constructives", "trop large", etc. puisque le thread est maintenant fermé, un autre inconvénient de la tête de tuple-mémoire. TOUJOURS B>. Avec une exception, le mécanisme d'exception ne donne qu'un coup de pied s'il y a une exception.