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

Grz*_*ski 14 c c++ language-lawyer c++11 c++03

在C面向条件运营商求值10类型的int(即使它确实有专用_Bool型).参考C11 N1570草案:

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;
}
Run Code Online (Sandbox Code Playgroud)

输出b,我猜是指示bool类型.C++是否保证所有这些运算符总是评估为bool类型(与C相反)?

Arn*_*gel 12

不,因为运营商超载.之前已经提到过,但我可以给出表达模板的真实例子.通常,这个想法是允许使用与正常,急切使用逻辑运算符非常类似的语法来编写"惰性"表达式(即,实际上是函数对象或AST).通常,许多其他运算符,特别是算术运算符也被重载.

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

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

以前,在"纯"C++ 98中,在许多标准算法可以有效使用之前,通常需要编写许多命名函数或函数对象.

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

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


oua*_*uah 11

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

例如:

(C++ 11,5.9p1关系运算符)"[...]结果的类型是bool."

编辑:为了完整起见,上面列出的所有操作符都可以重载,因此可以更改生成的类型.见阿恩沃格尔回答现实生活中的例子.

  • 假设他们没有被覆盖. (11认同)
  • 啊,"nitpicker的角落"又回来了:) (8认同)
  • @Bulletmagnet这不仅仅是一个问题,因为C++中的大量比较将涉及用户定义的运算符,它们可以(但不应该)返回任何类型. (8认同)