2012-03-08 48 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;