2012-03-08 253 views
7

通過嘗試,我開始知道有必要在cout語句中將條件運算符括起來。這裏一個小例子: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; 
} 

輸出是:

42 
42 
1 

爲什麼需要這個支架?這兩種情況下都知道條件運算符的結果類型,不是嗎?

回答

13

?:運算符的優先級低於<<運算符。即,編譯器把你的最後一句話是:

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

哪個會先流(a!=0)布爾值來清點。然後,該表達式的結果(即對cout的引用)將被轉換爲用於?:運算符的適當類型(即void*:請參閱http://www.cplusplus.com/reference/iostream/ios/operator_voidpt/),並取決於該值是否爲真(即,cout是否具有沒有錯誤標誌設置),它將抓取值42或值-42。最後,它會拋棄該值(因爲沒有使用它)。

+0

只需注意,'cout <<'返回'cout',而不是任何關於有效狀態的內容。 failbit/badbit將被設置,但是'(std :: cout <<(a!= 0))'總是返回對'std :: cout'的引用。 '-42.0f'永遠不會被返回,因爲那個引用總是布爾值求值爲true。 – 2012-03-08 14:53:35

+0

謝謝,甚至沒有考慮優先次序 – m47h 2012-03-08 15:01:06

+1

@SamDeHaan:是的。對不起,我的解釋可能有點sl in。表達式「cout << x」返回cout。但爲了評估表達式「cout?a:b」,必須先將cout轉換爲某個值,這是操作符的一個有效操作數。在這種情況下,它是(操作員無效*)完成這項工作。如果設置了錯誤標誌,那麼該運算符返回NULL。請參閱: 2012-03-08 15:50:18

4

因爲<<的優先級高於?

有趣的練習:

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

接招,編碼恐怖!

您的代碼等同於:

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

它輸出1因爲,(a != 0) == true;