if (cin >> x) - 为什么可以使用该条件?
整个夏天我一直在使用“Accelerated C++”来学习C++,有一个概念我似乎不太理解。
为什么
int x;
if (cin >> x){}
相当于
cin >> x;
if (cin){}
通过查看代码,在我看来我们正在使用 cin 作为变量。但是,我认为这是一个功能。当 x 具有我们在键盘中输入的任何值时,为什么我们可以以这种方式使用 cin?
I have been using "Accelerated C++" to learn C++ over the summer, and there's a concept which I don't seem to understand properly.
Why is
int x;
if (cin >> x){}
equivalent to
cin >> x;
if (cin){}
By looking at the code, it seems to me that we're using cin as a variable. But, I thought it was a function. Why can we use cin in this way when it is x that has whatever value we input into our keyboard?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
cin
是类istream
的对象 代表标准输入流。它对应于cstdio
流stdin
。流的运算符>>重载返回对同一流的引用。流本身可以通过转换运算符在布尔条件下评估为 true 或 false。
cin
提供格式化流提取。操作cin>> x;
其中“x”是一个 int,如果是非数字值,则会失败
进入。因此:
如果您输入字母而不是数字,将返回
false
。这个网站上的使用 C++ I/O 的提示和技巧也会对您有所帮助。
cin
is an object of classistream
that represents the standard input stream. It corresponds to thecstdio
streamstdin
. The operator>>
overload for streams return a reference to the same stream. The stream itself can be evaluated in a boolean condition to true or false through a conversion operator.cin
provides formatted stream extraction. The operationcin >> x;
where "x" is an int will fail if a non-numeric value is
entered. So:
will return
false
if you enter a letter rather than a digit.This website on tips and tricks using C++ I/O will help you too.
注意:答案在四年后更新,以解决 C++98/03 和 C++11(及更高版本)问题。
std::cin
是std::istream
的实例。该类提供了两个与该问题相关的重载。operator >>
将数据从流读取到目标变量(如果可能)。如果流的直接内容无法转换为目标变量的类型,则流将被标记为无效,并且目标变量保持不变。无论操作成功/失败,返回值都是对流的引用。operator void*()
(C++11 之前版本),将流引用转换为void*
指针,或显式运算符 bool()< /code> (C++11),它将流引用转换为布尔值。如果流有效,则此转换的结果是非空指针(C++11 之前的版本)或
true
(C++11),但空指针(C++11 之前的版本) 11) 或false
(C++11)(如果流无效)。if
语句需要一个布尔值、一个整数或一个指针作为要测试的数量。std::cin >> 的结果x
是对istream
的引用,它不是以上任何一个。但是,istream
类确实具有那些转换运算符,可用于将istream
引用转换为可在if
语句中使用的内容。它是该语言用于if
测试的特定于版本的转换运算符。由于读取失败会将流标记为无效,因此如果读取不起作用,if
测试将失败。C++11 之前使用更复杂的
operator void*
转换成员的原因是,直到 C++11 才扩展了现有的explicit
关键字适用于转换运算符和构造函数。非显式的操作符 bool()
会给程序员带来太多搬起石头砸自己脚的机会。operator void*()
也存在问题。 “safe bool idiom”本来是一个解决方案,但简单地扩展显式
就可以完成 safe bool idiom 所完成的工作,并且无需使用大量 SFINAE 魔法。Note: Answer updated four years after the fact to address both C++98/03 and C++11 (and beyond).
std::cin
is an instance of astd::istream
. That class provides two overloads that pertain to this question.operator >>
reads data from the stream into the target variable if that is possible. If the immediate contents of the stream cannot be translated into the type of the target variable, the stream is instead marked as invalid and the target variable is left untouched. Regardless of the success/failure of the operation, the return value is a reference to the stream.operator void*()
(pre-C++11), which converts the stream reference to avoid*
pointer, orexplicit operator bool()
(C++11), which converts the stream reference to a boolean. The result of this conversion is a non-null pointer (pre-C++11) ortrue
(C++11) if the stream is valid, but the null pointer (pre-C++11) orfalse
(C++11) if the stream isn't valid.An
if
statement needs either a boolean, an integer, or a pointer as the quantity to be tested. The result ofstd::cin >> x
is a reference to anistream
, which is none of the above. However, the classistream
does have those conversion operators which can be used to transform theistream
reference to something usable in anif
statement. It is the version-specific conversion operator that the language uses for theif
test. Since failure to read marks the stream as invalid, theif
test will fail if the read didn't work.The reason for the more convoluted
operator void*
conversion member prior to C++11 is that it wasn't until C++11 that the already existingexplicit
keyword was extended to apply to conversion operators as well as constructors. A non-explicitoperator bool()
would have presented far too many opportunities for programmers to shoot themselves in the foot. There are problems withoperator void*()
as well. The "safe bool idiom" would have been a fix, but simply extendingexplicit
accomplished exactly what the safe bool idiom accomplishes, and without having to use a lot of SFINAE magic.cin
是istream
类型的(全局)变量,而不是函数。istream
类重写>>
运算符来执行输入并返回对调用它的对象 (cin
) 的引用。cin
is a (global) variable of typeistream
, not a function.The
istream
class overrides the>>
operator to perform input and return a reference to the object you called it on (cin
).cin
是std
命名空间中的变量。operator>>
返回对cin
的引用,因此您可以编写:cin >>>一个>> b
,而不是cin >>一个;辛>> b;
cin
is variable instd
namespace.operator>>
return reference tocin
, because of it you can write:cin >> a >> b
, instead ofcin >> a; cin >> b;
上面的答案内容丰富。这里我只是补充一下。
std::cin
是istream
类的对象,表示与stdin< 对应的标准输入流(即键盘) C 流中的/code>。
cin>> x
首先会从标准输入流中读取一个 int 并将其分配给x
。之后返回对 cin 的自引用。所以函数调用cin>>的返回值是x
仍然是cin
。因此,从 if 条件来看,
if(cin)
和if(cin >> x)
彼此相似。标准IO库为流定义了一个像这样的函数(取决于实现):或者
从这两个声明,我们知道它们强制转换流类型 直接或间接(通过
void*
pinter 到bool
这是显而易见的)到bool
类型。在这两个函数中,它们依赖于一些基本的IO steam状态(类字段)来确定是否返回false或true(对于
void*
情况,它是nullptr
或不)。cin
是类istream
的一个实例,它继承了casting-to-bool 函数。所以它有效!The answers above are informative. Here I just give an extra comment.
std::cin
is an object of classistream
and represents the standard input stream (i.e. the keyboard) which corresponds tostdin
in C stream.cin >> x
would firstly read an int from the standard input stream and assignment it tox
. After that return a self reference tocin
. So the return value of function callcin >> x
is stillcin
.So from the point of if condition,
if(cin)
andif(cin >> x)
resemble each other. The standard IO Library defines a function for the stream like this (depends on implementation):or
From this two declarations, we know they cast the stream type directly or indirectly(through
void*
pinter tobool
which is obvious) tobool
type.Within this two functions, they depends on some basic IO steam statuses(class fields) to determine whether return false or true (for
void*
case, it isnullptr
or not).cin
is an instance of classistream
which inherits the casting-to-bool function. So it works!因为表达式的结果
求值。
在读取流后
because the result of the expression
evaluates to
after the stream is read.
std::cin
是std::istream
类的实例。cin>> x
只是调用 cin 对象上的函数。您可以直接调用该函数:为了允许您一次读取多个变量,
operator>>
函数返回对其调用的流的引用。您可以调用:或 等效:
或:
难题的最后一部分是
std::istream
可转换为bool
。布尔值是相当于调用
!fail()
。因此,在以下代码中:
bool readOK = !stream.fail();
可以简化为bool readOK = stream;
。您不需要单独的
bool
来存储流状态,因此只需执行if (stream)
即可。删除临时
stream
变量会得到if (std::cin.operator >>(x))
。使用运算符直接让我们回到原始代码:
std::cin
is an instance of thestd::istream
class.cin >> x
is just calling a function on thecin
object. You can call the function directly:To allow you to read multiple variables at once the
operator >>
function returns a reference to the stream it was called on. You can call:or equivalently:
or:
The final part of the puzzle is that
std::istream
is convertible tobool
. The bool isequivalent to calling
!fail()
.So in the following code:
bool readOK = !stream.fail();
can be reduced to justbool readOK = stream;
.You don't need a separate
bool
to store the stream state so can just doif (stream)
.Removing the temporary
stream
variable givesif (std::cin.operator >>(x))
.Using the operator directly gets us back to the original code:
1)
cin
是istream
的一个实例,参见http://www.cplusplus.com/reference/iostream/cin/。2)
istream
的>>
运算符将返回其左操作数,在本例中为cin
,参见 http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/。如果没有从cin
中提取字符,则该运算符会将failbit
设置为 on,以防读取器已完成EOF
,因此不会再有字符阅读。3) 与上面的2)一样,当读取操作后评估条件时,
if (cin >> x)
应该类似于if (cin)
,参考此链接 http://www.cplusplus.com/reference/ios/ios/ Operator_bool/ 你将会看到,这个if
块将返回:如果至少设置了
failbit
或badbit
之一,则返回一个空指针。否则为其他值(对于 C++98 标准)。如果至少设置了这些错误标志之一,则该函数返回 false,否则返回 true。 (对于 C++11 标准)
1)
cin
is an instance ofistream
, see http://www.cplusplus.com/reference/iostream/cin/.2) the
>>
operator ofistream
will return its left operand, in this case it iscin
, see http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/. This operator will setfailbit
on if no characters were extracted from thecin
, in case the reader has finishedEOF
so there will be no more character to read.3) As of the 2) above, when the condition is evaluated after the reading operation,
if (cin >> x)
should be likeif (cin)
, refer to this link http://www.cplusplus.com/reference/ios/ios/operator_bool/ you will see that, thisif
block will return:A null pointer if at least one of
failbit
orbadbit
is set. Some other value otherwise (for C++98 standard).The function returns false if at least one of these error flags is set, and true otherwise. (for C++11 standard)
因为 cin 是类的对象,所以请阅读 http://www.cplusplus.com/reference 了解更多信息/iostream/cin/ 。
because cin is an object of class, read more on http://www.cplusplus.com/reference/iostream/cin/ .