C++ if (cin >> x) - 为什么你可以使用那个条件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6791520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
if (cin >> x) - Why can you use that condition?
提问by Muhsin Ali
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.
整个夏天我一直在使用“Accelerated C++”来学习 C++,有一个我似乎不太理解的概念。
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?
通过查看代码,在我看来,我们正在使用 cin 作为变量。但是,我认为这是一个函数。当 x 具有我们在键盘中输入的任何值时,为什么我们可以以这种方式使用 cin ?
回答by
cin
is an object of class istream
that represents the standard input stream. It corresponds to the cstdio
stream stdin
. 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
是istream
表示标准输入流的类的对象。它对应于cstdio
流stdin
。>>
流的运算符重载返回对同一流的引用。流本身可以通过转换运算符在布尔条件中评估为真或假。
cin
provides formatted stream extraction. The operation
cin >> x;
cin
提供格式化流提取。操作
cin >> x;
where "x" is an int will fail if a non-numeric value is entered. So:
如果输入非数字值,其中 "x" 是 int 将失败。所以:
if(cin>>x)
will return false
if you enter a letter rather than a digit.
false
如果您输入字母而不是数字,将返回。
This website on tips and tricks using C++ I/Owill help you too.
这个关于使用 C++ I/O 的提示和技巧的网站也会对您有所帮助。
回答by David Hammen
Note: Answer updated four years after the fact to address both C++98/03 and C++11 (and beyond).
注意:答案在四年后更新,以解决 C++98/03 和 C++11(及更高版本)的问题。
std::cin
is an instance of a std::istream
. That class provides two overloads that pertain to this question.
std::cin
是 a 的一个实例std::istream
。该类提供了与此问题相关的两个重载。
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.- Either
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.
operator >>
如果可能,从流中读取数据到目标变量中。如果流的直接内容无法转换为目标变量的类型,则该流将被标记为无效,并且目标变量保持不变。无论操作成功/失败,返回值都是对流的引用。- 任一
operator void*()
(预C ++ 11),其将流参照void*
指针,或explicit operator bool()
(C ++ 11),其将流参考一个布尔值。true
如果流有效,则此转换的结果是非空指针 (pre-C++11) 或(C++11),但空指针 (pre-C++11) 或false
(C++11) ) 如果流无效。
An if
statement needs either a boolean, an integer, or a pointer as the quantity to be tested. The result of std::cin >> x
is a reference to an istream
, which is none of the above. However, the class istream
does have those conversion operators which can be used to transform the istream
reference to something usable in an if
statement. It is the version-specific conversion operator that the language uses for the if
test. Since failure to read marks the stream as invalid, the if
test will fail if the read didn't work.
一条if
语句需要一个布尔值、一个整数或一个指针作为要测试的数量。的结果std::cin >> x
是对 an 的引用istream
,这不是上述任何一个。但是,该类istream
确实具有那些可用于将istream
引用转换为if
语句中可用内容的转换运算符。它是语言用于if
测试的特定于版本的转换运算符。由于读取失败将流标记为无效,if
如果读取无效,测试将失败。
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 existing explicit
keyword was extended to apply to conversion operators as well as constructors. A non-explicit operator bool()
would have presented far too many opportunities for programmers to shoot themselves in the foot. There are problems with operator void*()
as well. The "safe bool idiom" would have been a fix, but simply extending explicit
accomplished exactly what the safe bool idiom accomplishes, and without having to use a lot of SFINAE magic.
operator void*
在 C++11 之前使用更复杂的转换成员的原因是,直到 C++11,已经存在的explicit
关键字才被扩展为适用于转换运算符和构造函数。一个非明确的东西operator bool()
会给程序员提供太多的机会来射自己的脚。也有问题operator void*()
。“safe bool idiom”本来是一个修复,但简单地扩展就explicit
完全完成了safe bool idiom 所完成的工作,而不必使用很多SFINAE 魔法。
回答by SLaks
cin
is a (global) variable of type istream
, not a function.
cin
是一个(全局)类型的变量istream
,而不是一个函数。
The istream
class overrides the >>
operator to perform input and return a reference to the object you called it on (cin
).
本istream
类覆盖了>>
操作者进行输入,并返回到你把它称为对对象的引用(cin
)。
回答by Olympian
cin
is variable in std
namespace.
cin
是std
命名空间中的变量。
operator>>
return reference to cin
, because of it you can write: cin >> a >> b
, instead of cin >> a; cin >> b;
operator>>
返回对 的引用cin
,因为它你可以写:cin >> a >> b
,而不是cin >> a; cin >> b;
回答by Erix
because the result of the expression
因为表达式的结果
cin >> x
evaluates to
评估为
cin
after the stream is read.
读取流后。
回答by Zachary
The answers above are informative. Here I just give an extra comment.
上面的答案是信息性的。在这里,我只做一个额外的评论。
std::cin
is an object of class istream
and represents the standard input stream(i.e. the keyboard) which corresponds to stdin
in C stream.
std::cin
是一个类的对象,istream
代表标准输入流(即键盘),它对应stdin
于 C流。
cin >> x
would firstly read an int from the standard input stream and assignment it to x
. After that return a self reference to cin
. So the return value of function call cin >> x
is still cin
.
cin >> x
将首先从标准输入流中读取一个 int 并将其分配给x
. 之后返回对cin
. 所以函数调用的返回值cin >> x
仍然是cin
。
So from the point of if condition, if(cin)
and if(cin >> x)
resemble each other. The standard IO Librarydefines a function for the stream like this (depends on implementation):
所以从if 条件来看,if(cin)
和if(cin >> x)
彼此相似。标准IO 库为这样的流定义了一个函数(取决于实现):
explicit operator bool() const; // C++11
or
或者
operator void*() const; //C++98, C++2003
From this two declarations, we know they castthe stream typedirectly or indirectly(through void*
pinter to bool
which is obvious) to bool
type.
从这两个声明,我们知道他们投的流类型直接或间接(通过void*
品特到bool
这是显而易见的)来bool
输入。
Within this two functions, they depends on some basic IO steamstatuses(class fields) to determine whether return false or true (for void*
case, it is nullptr
or not).
在这两个函数中,它们依赖于一些基本的IO 流状态(类字段)来确定是否返回 false 或 true(void*
例如,是否nullptr
)。
cin
is an instance of class istream
which inherits the casting-to-boolfunction. So it works!
cin
是一个类的实例,istream
它继承了cast-to-bool函数。所以它有效!
回答by Ryan Le
1) cin
is an instance of istream
, see http://www.cplusplus.com/reference/iostream/cin/.
1)cin
是 的一个实例istream
,参见http://www.cplusplus.com/reference/iostream/cin/。
2) the >>
operator of istream
will return its left operand, in this case it is cin
, see http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/. This operator will set failbit
on if no characters were extracted from the cin
, in case the reader has finished EOF
so there will be no more character to read.
2) 的>>
运算符istream
将返回其左操作数,在本例中为cin
,请参见http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/。failbit
如果没有从 中提取字符,则此运算符将设置为on cin
,以防读取器已完成,EOF
因此将不再有字符可读取。
3) As of the 2) above, when the condition is evaluated after the reading operation, if (cin >> x)
should be like if (cin)
, refer to this link http://www.cplusplus.com/reference/ios/ios/operator_bool/you will see that, this if
block will return:
3)如上面的2),当读取操作后评估条件时,if (cin >> x)
应该是这样的if (cin)
,参考这个链接http://www.cplusplus.com/reference/ios/ios/operator_bool/你会看到,此if
块将返回:
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)
如果至少设置了
failbit
或之一,badbit
则为空指针。其他一些值(对于 C++98 标准)。如果至少设置了这些错误标志之一,则该函数返回 false,否则返回 true。(对于 C++11 标准)
回答by Alan Birtles
std::cin
is an instance of the std::istream
class.
std::cin
是std::istream
类的一个实例。
cin >> x
is just calling a function on the cin
object. You can call the function directly:
cin >> x
只是在cin
对象上调用一个函数。您可以直接调用该函数:
cin.operator >>(x);
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:
为了允许您一次读取多个变量,该operator >>
函数返回对其调用的流的引用。您可以致电:
cin >> x >> y;
or equivalently:
或等效地:
cin.operator >>(x).operator >>(y);
or:
或者:
std::istream& stream = cin.operator >>(x);
stream.operator >>(y);
The final part of the puzzle is that std::istream
is convertibleto bool
. The bool is
equivalent to calling !fail()
.
拼图的最后一部分是std::istream
可以转换为bool
. bool 相当于调用!fail()
.
So in the following code:
所以在下面的代码中:
int x;
std::istream& stream = std::cin.operator >>(x);
bool readOK = !stream.fail();
if (readOK)
{
std::cout << x << "\n";
}
bool readOK = !stream.fail();
can be reduced to just bool readOK = stream;
.
bool readOK = !stream.fail();
可以减少到刚刚bool readOK = stream;
。
You don't need a separate bool
to store the stream state so can just do if (stream)
.
您不需要单独的bool
来存储流状态,所以可以只做if (stream)
.
Removing the temporary stream
variable gives if (std::cin.operator >>(x))
.
删除临时stream
变量给出if (std::cin.operator >>(x))
.
Using the operator directly gets us back to the original code:
直接使用运算符让我们回到原来的代码:
int x;
if (std::cin >> x)
{
std::cout << x << "\n";
}
回答by Emil Condrea
because cin is an object of class, read more on http://www.cplusplus.com/reference/iostream/cin/.
因为 cin 是类的对象,请在http://www.cplusplus.com/reference/iostream/cin/上阅读更多内容。