2010-07-15 29 views
8

Così mi sono imbattuto in qualcosa di interessante che non mi ero reso conto dell'operatore ternario (almeno in Visual C++ 98-2010). Come indicato in http://msdn.microsoft.com/en-us/library/e4213hs1(VS.71).aspx se sia l'espressione che l'espressione condizionale sono valori l, il risultato è un valore l.C++ operatore ternario

Naturalmente normalmente in C/C++ devi scrivere qualcosa come:

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

e mai nemmeno a cuore il coinvolgimento valore r/l-value, e in questo caso né 1 né 0 sono convertibili in valori l.

Tuttavia, prendere qualcosa come:

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

sia yez sono L-valori e loro, o più precisamente, uno di questi è risultato effettivo dell'operatore ternario (non il suo valore memorizzato) che non è necessariamente ovvio (almeno non ci avevo mai pensato a lungo).

Ma, cosa che porta a è la capacità di scrivere il seguente

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

che assegna 99 al y se x == 1 o 99 per z se x! = 1

I Non ho mai visto quello descritto da nessuna parte e in tutte le discussioni che ho letto sull'uso (o, solitamente, se usare) dell'operatore ternario.

Naturalmente funziona solo se entrambi l'espressione e condizionale espressione sono L-valori simile

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

fallisce la compilazione perché 0 è un valore di R felicemente rilevato dal compilatore.

E questo funziona solo se si include la parentesi

x == 1 ? y : z = 99;

è qualcosa di completamente diverso, che assegna 99 alla Z solo se (x! = 1) e la parte bella è che entrambe le parti sono ancora l -valori quindi c'è il serio buco del culo di cose come (x == 1 ? y : z = 99) = 100 do (assegna da 100 a yo z a seconda della verità di x == 1, stomping sull'assegnazione z = 99 se x == 1 è falso)

Quindi, questo mi porta alle mie domande:

A) È questa parte dell'attuale standard C++ (che sembra come sarebbe) e non solo una cosa Microsoft: ho cercato ma non sono riuscito, finora, a trovare queste informazioni.

B) Se questo è ampiamente realizzato e ho vissuto sotto una roccia? Non l'ho mai visto usato in nessun codice che io possa ricordare, e non l'ho mai visto menzionato quando viene discusso l'operatore ternario.

C) Devo uscire più spesso?

+1

R) Sì, secondo il mio pallido ricordo B) Sì, e c'è qualche più spazio là sotto? C) Sarebbe di aiuto? Con Cosa? – peterchen

+0

(B) Quando l'ignoranza è beatitudine, 'è follia essere saggi. –

+1

Non l'hai visto prima perché è difficile da leggere. Il codice di difficile lettura è dannoso per la manutenibilità. –

risposta

10

A) Sì, questo fa parte dello standard.

B) Non è ampiamente compreso, anche se potrebbe essere qui su SO.C'è una ragione per cui è stata votata la funzione nascosta n. 1 di C++: Hidden Features of C++?.

C) Nessun commento. :)

Personalmente, raccomando di non usare questa funzione. È molto meno intuitivo rispetto all'utilizzo delle dichiarazioni if/else e chiaramente non tutti ne sono a conoscenza.

Contro il mio stesso avvertimento, in realtà ho provato a usarlo una volta per un progetto personale, e mi sono bruciato mancando le parentesi e sprecando 30 minuti cercando di trovare l'errore.

+0

Beh, mi piacerebbe averlo incontrato prima di pubblicare ... :) ho guardato ma chiaramente l'ho perso. – Ruddy

2

Non l'hai mai visto usato perché questo uso è meno intuitivo e leggibile rispetto a quello più comune. Non l'ho mai visto usato in questo modo nel codice di produzione, e spero di non vederlo mai.

Ricorda Herb Sutter & Andrei Alexandrescu's C++ Coding Standards, regola 6: "La correttezza, la semplicità e la chiarezza vengono prima di tutto".

+0

Non sto certamente sostenendo il suo utilizzo - solo una curiosità a questo punto – Ruddy

+0

@Ruddy: stavo solo rispondendo a B. Non ero sicuro di A (anche se ero al 99% che era vero) o C :) –

3

A. Sì. § [expr.cond]/4:

Se il secondo e terzo operandi sono lvalue e hanno lo stesso tipo, il risultato è di questo tipo ed è un Ivalue ...

(Nota che è non vero in C. esplicitamente scritto nello standard C99, nota 93, "un'espressione condizionale non produce un lvalue.")

B. non credo che è ampiamente usato come la l'uso è piuttosto oscuro. E 'più comune vedere

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

FWIW: ho verificato in Visual 2010 conforme alla nota 93, in quanto si otterrà un errore di compilazione ("... l'operando sinistro deve essere il valore-l") quando si tenta di compilare '(x == 1? Y: z) = 100; 'in un file .c (straight-c). – Ruddy