是条件表达式C++总是布尔类型

Are conditional expressions in C++ always of bool type?

本文关键字:布尔 类型 C++ 条件 表达式      更新时间:2023-10-16

在 C 中,面向条件的运算符计算为 int 类型的 10(即使它确实具有专用的_Bool类型)。参考C11 N1570草案:

C11 §6.5.8/6 关系运算符

每个运算符<(小于)、>(大于)、<=(小于) 或等于),>=如果 指定的关系为真,如果为假,则为 0。107)结果有 键入 int

C11 §6.5.9/3 相等运算符

==(等于)和!=(不等于)运算符类似于 关系运算符,但其优先级较低。108) 每个 如果指定的关系为真,则运算符生成 1,如果 是假的。结果的类型为 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 相反)?

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

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

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

以前,在"纯"C++98 中,通常需要编写大量命名函数或函数对象,然后才能有效使用许多标准算法。

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

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

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

例如:

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

编辑:为了完整起见,上面列出的所有运算符都可以重载,因此可以更改结果类型。参见Arne Vogel的答案,了解现实生活中的例子。