2010-07-15 19 views
8

donc je suis tombé sur quelque chose d'intéressant que je ne savais pas à propos de l'opérateur ternaire (au moins dans Visual C++ 98-2010). Comme indiqué dans http://msdn.microsoft.com/en-us/library/e4213hs1(VS.71).aspx si à la fois l'expression et l'expression conditionnelle sont des valeurs l, le résultat est une valeur l.C++ opérateur ternaire

Bien sûr normalement dans c/C++ vous écririez quelque chose comme:

int value = (x == 1) ? 1 : 0;

et ne se soucient même de la valeur r/l valeur implication, et dans ce cas ni 1 ni 0 sont convertibles en valeurs-l.

Cependant, prendre quelque chose comme:

int value = (x == 1) ? y : z;

y et z sont l valeurs et elles, ou plus précisément, l'un d'entre eux est le résultat réel de l'opérateur ternaire (non sa valeur stockée) qui n'est pas forcément évident (du moins je n'y avais jamais pensé).

Mais, ce qui conduit à est la possibilité d'écrire le

suivant

(x == 1 ? y : z) = 99;

qui attribue 99 à y si x == 1 ou 99 à z si x! = 1

I Je n'ai jamais vu cela décrit nulle part et dans toutes les discussions que j'ai lues au sujet de l'utilisation (ou, en général, de l'utilisation ou non) de l'opérateur ternaire.

Bien sûr, il ne fonctionne que si l'expression et conditionnelle d'expression sont l-valeurs quelque chose comme

(x == 1 ? 0 : z) = 99;

ne parvient pas à compiler car 0 est une valeur r comme heureusement souligné par le compilateur.

Et cela ne fonctionne que si vous incluez la parenthèse

x == 1 ? y : z = 99;

est tout autre chose qui affecte 99 à z que si (x! = 1) et la part belle est que les deux parties sont encore l -values ​​donc il y a le rat-hole sérieux de ce que font (x == 1 ? y : z = 99) = 100 (il assigne 100 à y ou z selon la vérité de x == 1, piétinant sur l'affectation z = 99 si x == 1 est faux)

Alors, cela me conduit à mes questions:

A) Est-ce que cela fait partie du standard C++ actuel (ce qui semble être le cas) et pas seulement une chose de Microsoft - J'ai regardé mais j'ai échoué, jusqu'à présent, à trouver cette information.

B) Si cela est largement réalisé et je l'ai vécu sous un rocher? Je ne l'ai jamais vu utilisé dans un code dont je me souvienne, et je ne l'ai jamais vu mentionné quand l'opérateur ternaire est discuté.

C) Ai-je besoin de sortir plus souvent?

+1

A) Oui selon ma mémoire faible B) Oui, et est-il un plus de place là-dessous? C) Cela aiderait-il? Avec quoi? – peterchen

+0

(B) Lorsque l'ignorance est une félicité, c'est une folie d'être sage. –

+1

Vous ne l'avez pas vu auparavant parce que c'est difficile à lire. Le code difficile à lire est mauvais pour la maintenabilité. –

Répondre

10

A) Oui, cela fait partie de la norme.

B) Ce n'est pas largement réalisé, mais il peut être ici sur le SO.Il y a une raison pour laquelle il a été voté la fonctionnalité cachée n ° 1 de C++: Hidden Features of C++?.

C) Aucun commentaire. :)

Personnellement, je recommande de ne pas utiliser cette fonction. Il est beaucoup moins intuitif que d'utiliser if/else déclarations, et clairement tout le monde ne le sait pas. En dépit de mon propre avertissement, j'ai essayé d'utiliser ceci une fois sur un projet personnel, et j'ai été brûlé en manquant les parenthèses et gaspiller 30 minutes essayant de trouver l'erreur.

+0

Eh bien, j'aurais aimé être tombé dessus avant que je poste :) ... J'ai regardé mais clairement manqué. – Ruddy

2

Vous ne l'avez jamais vu utilisé parce que cette utilisation est moins intuitive et lisible que la plus courante. Je ne l'ai jamais vu utilisé de cette manière dans le code de production, et j'espère ne jamais le voir.

Rappelez-vous Herb Sutter & C++ Coding Standards d'Andrei Alexandrescu, règle 6: "L'exactitude, la simplicité, et la clarté viennent en premier."

+0

Je ne préconise certainement pas son utilisation - simplement une curiosité à ce stade – Ruddy

+0

@Ruddy: Je répondais juste à B. Je n'étais pas sûr de A (bien que j'étais à 99% que c'était vrai) ou C :) –

3

A. Oui. § [expr.cond]/4:

Si les deuxième et troisième opérandes sont lvalues ​​et ont le même type, le résultat est de ce type et une lvalue ...

(note qu'il est pas vrai C. explicitement écrit dans la norme C99, note 93, « une expression conditionnelle ne donne pas une lvalue. »)

B. Je ne pense pas qu'il est largement utilisé comme l'utilisation est assez obscure. Il est plus fréquent de voir

if (x == 1) 
    y = 99; 
else 
    z = 99; 
+0

FWIW: J'ai vérifié dans Visual 2010 est conforme à la note de bas de page 93, dans le sens où vous obtiendrez une erreur de compilation ("... l'opérande gauche doit avoir la valeur l") en essayant de compiler '(x == 1? Y: z) = 100; 'dans un fichier .c (straight-c). – Ruddy