为什么std::cin不能被隐式转换为bool?

4

《C++ Primer 第五版》第14章讨论了类型转换操作符:

Under earlier versions of the standard, classes that wanted to define a conversion to bool faced a problem: Because bool is an arithmetic type, a class-type object that is converted to bool can be used in any context where an arithmetic type is expected.

Such conversions can happen in surprising ways. In particular, if istream had a conversion to bool, the following code would compile:

int i = 42;
cin << i; // this code would be legal if the conversion to bool were not explicit!

This program attempts to use the output operator on an input stream. There is no << defined for istream, so the code is almost surely in error. However, this code could use the bool conversion operator to convert cin to bool. The resulting bool value would then be promoted to int and used as the left-hand operand to the built-in version of the left-shift operator. The promoted bool value (either 1 or 0) would be shifted left 42 positions.

输入流可以转换为布尔值,表示流的内部状态(成功或失败)。我们过去常做:

while(std::cin >> str)...

那么为什么这段代码不会编译呢?
int x = 0;
std::cin << x;

如果我使用显式转换,它就有效:

(bool)cin << 5; // works although bad

3
这个回答是否能解决你的问题?https://dev59.com/hFkS5IYBdhLWcg3wV1dy - 463035818_is_not_a_number
1
你的推理几乎正确。你唯一遗漏的细节是,即使转换被声明为显式,if (std::cin >> x)也是允许的,就像我在上面链接的问答中解释的那样。 - 463035818_is_not_a_number
这就是为什么早期的转换并不像布尔类型一样简单。它是到一种可以在布尔上下文中被中断的类型(不是确切的词)。因此,我们过去常常返回成员函数指针。这些指针可能为空或指向某个地址,如果放置在true或false的布尔上下文中,比如 while (cin >> val) 将返回一个流,然后会转换为类似指针的对象,它是整数类型,因此可以用于强制退出循环。旧时光荣岁月真是有趣。 - Martin York
1个回答

5

operator bool被声明为explicit,因此不应该隐式转换为布尔值:

bool b = std::cin; // Error

所以你需要明确地将cin转换为布尔值才能使其工作:
bool b {std::cin}; // OK, explicitly converting

所以当你尝试调用时

std::cin << 5;

由于该类仅允许显式转换,而您期望进行隐式转换,因此它无法编译。以下是解决方案:
bool(std::cin) << 5;

现在,为什么while(std::cin >> x)能够编译?标准保证了在这种情况下会发生显式转换为bool。请参阅有关此问题评论中链接的出色文章

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接