2012-03-08 12 views
7

Provando, sono venuto a sapere che è necessario mettere le parentesi attorno a un operatore condizionale in un'istruzione cout. Ecco un piccolo esempio:Operatore condizionale utilizzato nella dichiarazione cout

#include <iostream> 

int main() { 
    int a = 5; 
    float b = (a!=0) ? 42.0f : -42.0f; 
    // works fine 
    std::cout << b << std::endl; 
    // works also fine 
    std::cout << ((a != 0) ? 42.0f : -42.0f) << std::endl; 
    // does not work fine 
    std::cout << (a != 0) ? 42.0f : -42.0f; 

    return 0; 
} 

L'output è:

42 
42 
1 

Perché questa fascia necessario? Il tipo risultante dell'operatore condizionale è noto in entrambi i casi, non è vero?

risposta

13

L'operatore ?: ha precedenza inferiore rispetto all'operatore <<. Vale a dire, il compilatore interpreta tua ultima affermazione come:

(std::cout << (a != 0)) ? 42.0f : -42.0f; 

dove verrà inizialmente in streaming il valore booleano di (a!=0) a cout. Quindi il risultato di tale espressione (cioè un riferimento a cout) sarà trasmesso a un tipo appropriato per l'uso nell'operatore?: (Ovvero void*: vedere http://www.cplusplus.com/reference/iostream/ios/operator_voidpt/) ea seconda che tale valore sia vero (ovvero, se cout ha nessun flag di errore impostato), prenderà il valore 42 o il valore -42. Infine, getterà quel valore lontano (dal momento che nulla lo usa).

+0

Solo una nota, 'cout <<' restituisce 'cout', non qualcosa sullo stato valido. failbit/badbit verrà impostato, ma '(std :: cout << (a! = 0))' restituisce sempre un riferimento a 'std :: cout'. '-42.0f' non dovrebbe mai essere restituito, dato che quel riferimento dovrebbe sempre booleano valutare su true. –

+0

grazie, non ho nemmeno pensato alle precedenze – m47h

+1

@SamDeHaan: sì. Scusate, forse ero un po 'sciatto nella mia spiegazione. L'espressione "cout << x" restituisce cout. Ma affinché l'espressione "cout? A: b" sia valutata, cout deve prima essere gettato su un valore che è un operando valido per l'operatore? :. In questo caso, è (operator void *) che fa il lavoro. Questo operatore restituisce NULL se è impostato un flag di errore. Vedi:

4

Perché << ha precedenza superiore a ?.

Fun esercizio:

float ftest = std::cout << (a != 0) ? 42.0f : -42.0f; 

Take That, Coding Horror !!!

Il codice è equivalente a:

if (std::cout << (a != 0)) 
    42.0f; 
else 
    -42.0f; 

Produce 1 perché, bene, (a != 0) == true;

Problemi correlati