C++ 中的条件表达式总是 bool 类型吗?
Are conditional expressions in C++ always of bool type?
在 C 中,面向条件的运算符计算为类型 int
的 1
或 0
(即使它确实具有专用的 _Bool
类型)。参考 C11 N1570 draft:
C11 §6.5.8/6 Relational operators
Each of the operators <
(less than), >
(greater than), <=
(less than
or equal to), and >=
(greater than or equal to) shall yield 1 if the
specified relation is true and 0 if it is false.107) The result has
type int
.
C11 §6.5.9/3 Equality operators
The ==
(equal to) and !=
(not equal to) operators are analogous to the
relational operators except for their lower precedence.108) Each of
the operators yields 1 if the specified relation is true and 0 if it
is false. The result has type int
. For any pair of operands, exactly
one of the relations is true.
C11 6.5.13/3 Logical AND operator
The &&
operator shall yield 1 if both of its operands compare unequal
to 0; otherwise, it yields 0. The result has type int
.
C11 6.5.14/3 Logical OR operator
The ||
operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type 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 相比)?
与 C 相反,在 C++ 中,关系运算符、相等运算符和逻辑运算符(逻辑与、逻辑或和逻辑否定)都产生类型为 bool
的值。
例如:
(C++11, 5.9p1 Relational operators) "[...] The type of the result is bool."
编辑: 为了完整起见,上面列出的所有运算符都可以重载,因此可以更改结果类型。查看 Arne Vogel 的真实回答 。
否,因为运算符重载。之前已经提到过,但我可以给出 expression templates. The idea, generally, is to allow writing "lazy" expressions (that is, really, function objects or ASTs) 的真实示例,其语法与逻辑运算符的正常、急切使用非常相似。通常,许多其他运算符,特别是算术运算符也会被重载。
例如,Boost.Lambda 的一个设计目标是简化算法的使用:
std::string str;
// ...
std:.string::iterator firstA = std::find_if(str.begin(), str.end(), _1 == 'a' || _1 == 'A');
以前,在"pure" C++98中,通常需要编写大量的命名函数或函数对象,才能有效地使用许多标准算法。
自 C++11 起,Boost.Lambda 不再有用,因为 lambda 表达式已添加到核心语言中。仍然有许多 EDSL(嵌入式领域特定语言),其中 C++11 lambda 无法替换表达式模板,例如您可能希望以类似于 .NET 中的 LINQ 的方式直接从 C++ EDSL 生成 SQL 命令字符串,但作为可移植的库解决方案。另一个例子:VexCL 库使用表达式模板生成 GPU 内核。
这可能是将非布尔 return 类型用于重载逻辑运算符的唯一合法用途,但它通常不被认为是深奥的。
在 C 中,面向条件的运算符计算为类型 int
的 1
或 0
(即使它确实具有专用的 _Bool
类型)。参考 C11 N1570 draft:
C11 §6.5.8/6 Relational operators
Each of the operators
<
(less than),>
(greater than),<=
(less than or equal to), and>=
(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.107) The result has typeint
.C11 §6.5.9/3 Equality operators
The
==
(equal to) and!=
(not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has typeint
. For any pair of operands, exactly one of the relations is true.C11 6.5.13/3 Logical AND operator
The
&&
operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has typeint
.C11 6.5.14/3 Logical OR operator
The
||
operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has typeint
.
正如我所检查的,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 相比)?
与 C 相反,在 C++ 中,关系运算符、相等运算符和逻辑运算符(逻辑与、逻辑或和逻辑否定)都产生类型为 bool
的值。
例如:
(C++11, 5.9p1 Relational operators) "[...] The type of the result is bool."
编辑: 为了完整起见,上面列出的所有运算符都可以重载,因此可以更改结果类型。查看 Arne Vogel 的真实回答
否,因为运算符重载。之前已经提到过,但我可以给出 expression templates. The idea, generally, is to allow writing "lazy" expressions (that is, really, function objects or ASTs) 的真实示例,其语法与逻辑运算符的正常、急切使用非常相似。通常,许多其他运算符,特别是算术运算符也会被重载。
例如,Boost.Lambda 的一个设计目标是简化算法的使用:
std::string str;
// ...
std:.string::iterator firstA = std::find_if(str.begin(), str.end(), _1 == 'a' || _1 == 'A');
以前,在"pure" C++98中,通常需要编写大量的命名函数或函数对象,才能有效地使用许多标准算法。
自 C++11 起,Boost.Lambda 不再有用,因为 lambda 表达式已添加到核心语言中。仍然有许多 EDSL(嵌入式领域特定语言),其中 C++11 lambda 无法替换表达式模板,例如您可能希望以类似于 .NET 中的 LINQ 的方式直接从 C++ EDSL 生成 SQL 命令字符串,但作为可移植的库解决方案。另一个例子:VexCL 库使用表达式模板生成 GPU 内核。
这可能是将非布尔 return 类型用于重载逻辑运算符的唯一合法用途,但它通常不被认为是深奥的。