8
votes

Est-ce que chaque construction si elle est remplacée par une expression conditionnelle équivalente?

(Je n'ai pas un besoin sérieux pour cette réponse, je suis juste curieux.)

peut être remplacé par une expression conditionnelle équivalente à l'aide de l'opérateur conditionnel ?: ?


2 commentaires

En C et C ++, l'opérateur s'appelle l'opérateur conditionnel . Vous pouvez trouver cela utile si vous recherchez d'autres références.


Eh bien, merci je suis conscient de cela :) Je cherche d'autres références mais je n'ai pas réussi à trouver ce que je cherche.


8 Réponses :


1
votes

L'opérateur conditionnel s'attend à ce que les deux éléments suivants du ? code> soient des r devalues ​​(car le résultat d'un opérateur conditionnel est lui-même une rvalue) - donc pendant que je ne suis pas entièrement un expert sur le C / C ++ Standards, mon intuition serait que ce qui suit serait interdit (ou à défaut que, à l'échec du style de codage extrêmement médiocre ...): xxx pré>

alors que la version si elle serait assez standard : P>

if(condition) return x;
else return y;


4 commentaires

Merci Dave, oui (condition)? Retour x: Retour Y; n'est pas autorisé à ce que ce soit que retour x et retour y ne sont pas des expressions.La syntaxe de l'expression conditionnelle est (expr1)? EXPR2: EXPR3


Eh bien, pour la construction if-else vous avez suggéré de penser que ce sera une expression conditionnelle équivalente: retour (condition)? x: y


Oui, c'est équivalent - mais ce n'est pas un remplacement direct de la construction if-else, c'est une reprise du code (d'où mon dernier commentaire).


Par exemple, considérez cela à la place: si (condition) renvoie x; autre y = 2; - vous auriez un moment très difficile de convoquer cela en ternaire. ;)



1
votes

L'utilisation de l'opérateur conditionnel entraîne une expression et les deux résultats potentiels de l'opérateur conditionnel doivent être «compatibles» (convertibles au même type).

un si - else ne doit même pas nécessairement "renvoyer" tout type de même le même des deux branches.


0 commentaires

4
votes

à la surface de celui-ci, non. L'opérateur conditionnel est une expression (c'est-à-dire qu'il a une valeur), tandis que si / sinon est une déclaration (n'a donc aucune valeur). Ils remplissent différents "besoins" dans la syntaxe de langue.

Cependant, étant donné que vous pouvez ignorer les valeurs d'expression et que toute expression peut être transformée en une instruction en ajoutant un point-virgule, vous pouvez essentiellement émuler si / sinon avec une expression conditionnelle et Deux fonctions auxiliaires: xxx

Cependant, cela dit que je ne suis pas sûr que ce soit autre chose qu'une curiosité ...


6 commentaires

Remarque, que la valeur de retour du vide de type est également autorisée.


@hacker: édité - merci pour la pointe. N'a pas réalisé que vous pourriez avoir une expression nulle dans une clause conditionnelle!


Digressant légèrement, le type de vidage de retour n'est pas autorisé ici: int A = condition? if_block (): else_block (); ? (GCC 4.3.2)


@James: Comment ça jive avec la valeur de retour ignore? A-t-il un type INT implicite?


@Drew: GCC dit "Erreur: Valeur annulée non ignorée car il devrait être" in_my_example mais d'autres compilateurs peut-être seulement émettre un avertissement?


@James: Retour au type Bool Type de retour - Je n'étais pas à l'aise avec l'expression vide là-bas! (Même si les bools jetés sont un peu moins transparents).



1
votes
if( cond )
    break;
else
    a=b;
can not always be replaced by ?: operator. You can often (if not always) rethink your whole code to provide for this substitute, but generally you can't put anything that controls execution into ?:. break, return, loops, throw, etc.

0 commentaires

11
votes

Est-ce que toutes les constructions IF-else peuvent être remplacées par une expression conditionnelle équivalente à l'aide de l'opérateur conditionnel?

Non, vous avez demandé à cela à l'envers. Les "corps" de Si / SQUINT contiennent des déclarations, et il n'est pas possible de transformer chaque énoncé en expression , telle que tenter, tandis que les déclarations de pause, ainsi que des déclarations. De nombreuses "déclarations" sont vraiment des expressions déguisées, cependant: xxx

Toutes ces déclarations sont constituées d'une expression (incrément, affectation, appel de fonction, respectivement) et pourrait être transformé en expressions dans un état conditionnel.

Ainsi, inversons la question, car il semble que vous souhaitiez vraiment savoir à quel point les déclarations d'équivalent si / else sont aux expressions conditionnelles ternaires: peut toutes les expressions conditionnelles être remplacé par des déclarations équivalentes si / else? presque tous, oui. Un exemple commun est les relevés de retour: xxx

mais aussi d'autres expressions: xxx

qui commence à pointer vers le lieu où des expressions conditionnelles ne peut pas être facilement remplacé: initialisations . Puisque vous ne pouvez initialiser qu'un objet une fois, vous devez casser une initialisation qui utilise un conditionnel à l'aide d'une variable temporaire explicite: xxx

remarque ceci est beaucoup plus fastidieux / encombrant et nécessite quelque chose qui dépend de quelque type dépendant si quelque chose ne peut pas être construit par défaut et attribué.


5 commentaires

"Les" corps "de Si / sinon contiennent des déclarations, et il n'est pas possible de transformer toutes les instructions en une expression" - cela précise tout mon doute. :)


En outre, l'initialisation d'une variable Const ne peut pas être divisée dans une instruction IF: const t obj = cond? T: f; <= ne peut pas changer sans enlever le const.


Curieusement, C ++ 0x Permet de transformer tout tas de déclarations dans une expression utilisant des Lambdas.


Bill: 'Obj' pourrait facilement être fait const dans mon exemple avec t obj (TEMP);


Roger: Oui, mais vous avez besoin de la deuxième variable. Je n'essayais pas de corriger votre exemple final, il suffit d'ajouter un autre instance où?: Ne peut pas être converti de manière énergique.



0
votes

gcc a Expression de l'instruction , en l'utilisant, vous pouvez réécrire si instructions à l'équivalent ?: expressions: xxx

EDIT: Le void CASTS sert deux objectifs. Les subexpressions dans ?: doivent avoir le même type, et sans le Void Le compilateur peut imprimer Avertissement: instruction sans effet . xxx


3 commentaires

Je pense que vous devriez mettre le void trucs autour des expressions de déclaration - l'opération de distribution n'est pas distributive entre les deuxième et troisième opérandes.


@LitB: Pouvez-vous écrire un court exemple où mon placement annulé est faux?


Sambowry: échoue avec GCC 4.3.3: Echo 'int Main () {(vide) (1? ({"ABC";}): ({42;})); } '| g ++ -x c ++ - -c



1
votes

en principe, oui: xxx

devient xxx

par rapport à l'utilisation de procédures (qui sont plus naturels), cela permet BREAK , Continuer , Retour . Il nécessite une évaluation de A ne se terminer pas par Trueresult / falseresult mais si vous utilisez ces exceptions uniquement pour simuler si , ce ne sera pas un problème.


0 commentaires

2
votes

Non, bien sûr pas. Pour des raisons déjà mentionnées, et plus!

if(HRESULT hr = myInterface->myMethod())
{
    _com_raise_error(hr);
}


0 commentaires