C ++中的条件表达式是否总是bool类型?

时间:2015-01-22 14:45:12

标签: c++ c c++11 language-lawyer c++03

在C条件导向运算符中,求值为1类型的0int(即使它具有专用的_Bool类型)。参考C11 N1570 draft

  

C11§6.5.8/ 6 关系运算符

     

每个运营商<(小于),>(大于),<=(小于   或等于),如果>=(大于或等于),则产生1   指定的关系为真,如果为假,则为0。 107)结果为   输入int

     

C11§6.5.9/ 3 平等运营商

     

==(等于)和!=(不等于)运算符类似于   关系运算符,除了它们的优先级较低。 108)每个   如果指定的关系为真,则运算符为1,如果为,则为0   是假的。结果的类型为int。对于任何一对操作数,确切地说   其中一个关系是真的。

     

C11 6.5.13 / 3 逻辑AND运算符

     

如果两个操作数的比较不相等,&&运算符将产生1   到0;否则,它产生0.结果的类型为int

     

C11 6.5.14 / 3 逻辑OR运算符

     

如果其中任何一个操作数进行比较,||运算符将产生1   不等于0;否则,它产生0.结果的类型为int

我检查过C ++在这个问题上似乎有所不同,如下面的例子所示(见http://ideone.com/u3NxfW):

#include <iostream>
#include <typeinfo>

int main() {
    double x = 10.0;

    std::cout << typeid(x <= 10.0).name() << std::endl;

    return 0;
}

输出b,我猜这表示bool类型。 C ++是否保证所有这些运算符总是评估为bool类型(与C形成对比)?

2 个答案:

答案 0 :(得分:12)

不,因为运营商超载。之前已经提到过,但我可以给出expression templates的真实例子。通常,这个想法是允许写作&#34; lazy&#34;表达式(即,实际上是函数对象或AST),其语法与正常,急切使用逻辑运算符非常相似。通常,许多其他运算符,特别是算术运算符也会被重载。

例如,Boost.Lambda的一个设计目标是简化算法的使用:

std::string str;
// ...
std:.string::iterator firstA = std::find_if(str.begin(), str.end(), _1 == 'a' || _1 == 'A');

以前,在&#34; pure&#34;在C ++ 98中,在许多标准算法可以有效使用之前,通常需要编写许多命名函数或函数对象。

从C ++ 11开始,Boost.Lambda不再那么有用,因为lambda表达式已被添加到核心语言中。仍有许多EDSL(嵌入式域特定语言),其中C ++ 11 lambdas不能替代表达模板,例如,您可能希望以类似于.NET中的LINQ的方式直接从C ++ EDSL生成SQL命令字符串,但作为可移植库解决方案。另一个例子:VexCL库使用表达式模板生成GPU内核。

这可能是重载逻辑运算符的非bool返回类型的唯一合法使用,但它通常不被认为是深奥的。

答案 1 :(得分:11)

与C相反,在C ++中,关系运算符,相等运算符和逻辑运算符(逻辑AND,逻辑OR和逻辑否定)都产生类型为bool的值。

例如:

  

(C ++ 11,5.9p1关系运算符)&#34; [...]结果的类型是bool。&#34;

编辑:为了完整起见,上面列出的所有操作符都可以重载,因此可以更改生成的类型。请参阅Arne Vogel对现实生活的回答example