if(cin >> x) - 你为什么要使用这个条件?

Muh*_*Ali 48 c++ variables if-statement cin

我在夏天一直使用"Accelerated C++"来学习C++,并且有一个我似乎无法理解的概念.

为什么是

int x;
if (cin >> x){}
Run Code Online (Sandbox Code Playgroud)

相当于

cin >> x;
if (cin){}
Run Code Online (Sandbox Code Playgroud)

通过查看代码,在我看来,我们使用cin作为变量.但是,我认为这是一个功能.为什么我们可以以这种方式使用cin,因为它是x,它具有我们输入键盘的任何值?

小智 60

cinistream表示标准输入流的类的对象.它对应于cstdiostdin.>>流的运算符重载返回对同一流的引用.通过转换运算符,可以在布尔条件下将流本身评估为true或false.

cin提供格式化的流提取.操作 cin >> x;

如果输入非数字值,则"x"为int将失败.所以:

if(cin>>x)
Run Code Online (Sandbox Code Playgroud)

false如果您输入的是字母而不是数字,则会返回.

本网站提供有关使用C++ I/O的提示和技巧也将对您有所帮助.

  • @Muhsin:因为所有`if`都接受if表达式是布尔值,整数或指针.类`std :: istream`提供了将输入流转换为布尔值的能力,而这个转换运算符用于评估是否执行`if`分支或`else`分支. (3认同)

Dav*_*men 34

注意:答案在事后四年更新,以解决C++ 98/03和C++ 11(及更高版本).


std::cin是一个例子std::istream.该类提供了两个与此问题相关的重载.

  • operator >>如果可能,将数据从流中读取到目标变量中.如果流的直接内容无法转换为目标变量的类型,则将该流标记为无效,并保持目标变量不变.无论操作成功/失败,返回值都是对流的引用.
  • 任一operator void*()(预C++ 11),其将流参照void*指针,或explicit operator bool()(C++ 11),其将流参考一个布尔值.true如果流有效,则转换的结果是非空指针(前C++ 11)或(C++ 11),但空指针(前C++ 11)或false(C++ 11) )如果流无效.

if语句需要任一个布尔,整数,或作为数量要测试的指针.结果std::cin >> x是对a的引用istream,这不是上述内容.但是,该类istream确实具有那些转换运算符,可用于将istream引用转换为if语句中可用的内容.它是语言用于if测试的特定于版本的转换运算符.由于读取失败将流标记为无效,因此if如果读取不起作用,则测试将失败.

operator void*在C++ 11之前更复杂的转换成员的原因是,直到C++ 11,已经存在的explicit关键字被扩展为应用于转换运算符和构造函数.一个非明确的operator bool()会给程序员提供太多机会射击自己的机会.也存在问题operator void*()."安全bool成语"本来是一个解决方案,但只是延伸explicit完成了安全bool成语所完成的,而且不必使用很多SFINAE魔法.

  • 它不使用`operator bool`而是使用`operator void*`,operator bool允许它在算术上下文中使用,而operator void*可以防止这种情况,因为void是一个不完整的类型.在MSVC编译器的实现中,如果没有设置失败标志(无法为0,因此在布尔上下文中将其评估为"true"),则void*返回对象的地址;如果设置了任何标志,则返回0(评估为布尔值false). (5认同)
  • 根据 http://www.cplusplus.com/reference/ios/ios/operator_bool/ 它是 C++98 的 `operator void*()` 和 C++11 的 `operator bool()`。 (2认同)

SLa*_*aks 7

cin是类型的(全局)变量istream,而不是函数.

istream类覆盖了>>操作者进行输入,并返回到你把它称为对对象的引用(cin).


Oly*_*ian 7

cinstd命名空间中是变量.

operator>>返回引用cin,因为它你可以写:cin >> a >> b,而不是cin >> a; cin >> b;


Zac*_*ary 6

上面的答案是信息性的。在这里,我只做一个额外的评论。

std::cin是一个类的对象,istream代表标准输入流(即键盘),它对应stdin于 C

cin >> x将首先从标准输入流中读取一个 int 并将其分配给x. 之后返回对cin. 所以函数调用的返回值cin >> x仍然是cin

所以从if 条件来看,if(cin)if(cin >> x)彼此相似。标准IO 库为这样的流定义了一个函数(取决于实现):

explicit operator bool() const; // C++11
Run Code Online (Sandbox Code Playgroud)

或者

operator void*() const; //C++98, C++2003
Run Code Online (Sandbox Code Playgroud)

从这两个声明,我们知道他们流类型直接或间接(通过void*品特到bool这是显而易见的)来bool输入。

在这两个函数中,它们依赖于一些基本的IO 流状态(类字段)来确定是否返回 false 或 true(void*例如,是否nullptr)。

cin是一个类的实例,istream它继承了cast-to-bool函数。所以它有效!


Eri*_*rix 5

因为表达式的结果

cin >> x
Run Code Online (Sandbox Code Playgroud)

评估为

cin
Run Code Online (Sandbox Code Playgroud)

读取流后。