std::cin 如何同时返回布尔值和自身
How can std::cin return a bool and itself at the same time?
我正在读一本关于C++的书,里面说如果我使用>> 运算符,它会返回运算符左侧的对象,所以在这个例子中
std::cin >> value1;
代码返回 std::cin
。
但如果我这样做
while(std::cin >> value1)
我的代码将处于循环中,直到出现std::cin
错误,因此这必须意味着运算符返回一个bool
,当std::cin
不失败时为 true,在std::cin
失败时返回 false。
是哪一个?
[...]所以这必须意味着运算符返回一个布尔值[...]
不,它返回std::cin
(通过引用(。while(std::cin >> value);
之所以有效,是因为std::istream
(std::cin
的类型(有一个转换运算符。
转换运算符基本上允许将类隐式(如果它没有标记为explicit
(转换为给定类型。在这种情况下,std::istream
定义其operator bool
以返回是否发生了错误(通常failbit
(;
[std::ios_base::operator bool()]
如果流没有错误并且已准备好执行 I/O 操作,则返回
true
。具体来说,返回!fail()
.
explicit operator bool() const;
请注意,即使运算符是explicit
的(这不应该允许像if (std::cin);
这样的隐式转换(,在需要bool
的上下文中使用限定符时,限定符会被忽略,如if
、while
循环和for
循环。不过,这些都是例外,而不是规则。
下面是一个示例:
if (std::cin >> value); //OK, a 'std::istream' can be converted into a 'bool', which
//therefore happens implicitly, without the need to cast it:
if (static_cast<bool>(std::cin >> value)); //Unnecessary
bool b = std::cin >> value; //Error!! 'operator bool' is marked explicit (see above), so
//we have to call it explicitly:
bool b = static_cast<bool>(std::cin >> value); //OK, 'operator bool' is called explicitly
std::istream
(std::cin
作为对象的类(具有以下成员函数:
explicit operator bool() const;
如果对象处于错误状态,则返回 false,否则返回 true。这就是while(std::cin >> value1)
构造起作用的原因。在 C++11 之前,它有这个非显式函数:
operator void*() const;
如果对象处于错误状态,则返回空指针,达到相同的目的。
> std::cin
属于 std::istream
类型(这只是 std::basic_istream<char>
的typedef
(
如果您看到 basic_istream
的不同重载operator>>
,则它们都返回对 basic_istream
的引用。所以有一件事需要澄清,这里的operator>>
不返回bool
而是返回"std::cin
"本身。您不会看到任何返回bool
值的operator>>
。
所以现在的问题是,它如何将std::basic_istream
转换为bool
?
答案是:为此目的调用转换运算符。
std::basic_istream
从其父std::basic_ios
继承operator bool()
explicit operator bool() const;
这使得可以将std::basic_istream
对象转换为 bool
.人们很容易怀疑它被标记为explicit
(参见为什么它被标记为explicit
(,并且仍然在if
或while
中隐式转换为bool
。
这个问题的答案是if
或while
"隐式"使用显式转换。(见@R. Martinho Fernandes的回答(。所以if
,while
和for
是这种"对bool
的"内在转换"隐含发生的地方之一。
对流的操作返回对流的引用。
所以,不是bool
.
您可以将结果粘贴到if
条件中,原因与执行此操作的原因相同:
void* ptr = foo();
if (ptr) { /*...*/ }
而且,就此而言,这个:
int x = foo();
if (x) { /*...*/ }
这里的ptr
和x
都可以转换为bool
以在该条件下使用。在std::cin
的情况下,转换是通过std::ostream
类中的operator bool()
来实现的,该是为此任务明确添加的(双关语(。
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 变量定义到C++布尔值转换
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 重载更少,则运算符返回相反的布尔值
- 如何在保持其值的同时将 c++ 无符号字符变量转换为 char 变量
- 将此布尔值传递给此函数的最有效方法是什么?
- 如何设置 c++ 类的布尔值?
- 使用 MAKEWORD / MAKEWPARAM 使用布尔值而不是布尔值
- 将 10 个线程与原子布尔值同步
- 创建类似于布尔值的变量类型
- 布尔值向量的基于范围 for 循环
- 零点和布尔值之间的比较
- 简化对两个布尔值的 4 个 if/else 检查
- 无法创建带有布尔值和矢量的地图
- 对于完成布尔值设置为 true 后未停止的循环
- fstream / ifstream / ofstream 对象如何转换为布尔值
- C++:将值赋值给原始数据类型(例如布尔值)是原子操作吗?
- 在布尔值中设置额外的位使其同时为真和为假
- 在简单情况下,同时写并阅读布尔值的危险
- std::cin 如何同时返回布尔值和自身