我在夏天一直使用“Accelerated C ++”来学习C ++,并且有一个我似乎无法理解的概念。
为什么
int x;
if (cin >> x){}
相当于
cin >> x;
if (cin){}
通过查看代码,在我看来,我们使用cin作为变量。但是,我认为这是一个功能。为什么我们能以这种方式使用cin,因为它是x,它具有我们输入键盘的任何值?
答案 0 :(得分:59)
cin
是类istream
的对象,表示标准输入流。它对应于cstdio
流stdin
。流的运算符>>
重载返回对同一流的引用。通过转换运算符,可以在布尔条件下将流本身评估为true或false。
cin
提供格式化的流提取。操作
cin >> x;
如果非数字值为“x”,则int将失败 进入。所以:
if(cin>>x)
如果输入字母而不是数字,将返回false
。
tips and tricks using C++ I/O上的这个网站也会对你有帮助。
答案 1 :(得分:32)
注意:答案在事后四年更新,以解决C ++ 98/03和C ++ 11(以及更高版本)。
std::cin
是std::istream
的一个实例。该类提供了两个与此问题相关的重载。
operator >>
将数据从流中读取到目标变量中。如果流的直接内容无法转换为目标变量的类型,则将该流标记为无效,并保持目标变量不变。无论操作成功与否,返回值都是对流的引用。operator void*()
指针的void*
(pre-C ++ 11)或转换流引用的explicit operator bool()
(C ++ 11)到布尔值。如果流有效,则此转换的结果是非空指针(前C ++ 11)或true
(C ++ 11),但空指针(前C ++ 11)或false
(C ++ 11)如果流无效。 if
语句需要布尔值,整数或指针作为要测试的数量。 std::cin >> x
的结果是istream
的引用,它不是上述内容。但是,类istream
确实有一些转换运算符,可用于将istream
引用转换为if
语句中可用的引用。它是语言用于if
测试的特定于版本的转换运算符。由于读取失败将流标记为无效,因此如果读取不起作用,if
测试将失败。
在C ++ 11之前更复杂的operator void*
转换成员的原因是,直到C ++ 11,已经存在的explicit
关键字被扩展为应用于转换运算符以及建设者。一个非显式的operator bool()
会给程序员提供太多机会射击自己的机会。 operator void*()
也存在问题。 “安全bool成语”本来是一个修复,但只是延伸explicit
完成了安全bool成语完成的事情,而且不必使用大量的SFINAE魔法。
答案 2 :(得分:7)
cin
是istream
类型的(全局)变量,而不是函数。
istream
类会覆盖>>
运算符以执行输入并返回对您调用它的对象的引用(cin
)。
答案 3 :(得分:6)
cin
在std
命名空间中是变量。
operator>>
返回对cin
的引用,因为您可以写:cin >> a >> b
,而不是cin >> a; cin >> b;
答案 4 :(得分:4)
因为表达式的结果
cin >> x
评估为
cin
读取流后。
答案 5 :(得分:4)
以上答案内容丰富。在这里,我只是给予额外的评论。
std::cin
是类istream
的对象,代表标准输入流(即键盘),对应于C 流中的stdin
。
cin >> x
首先从标准输入流中读取一个int并将其分配给x
。之后返回cin
的自引用。因此,函数调用cin >> x
的返回值仍为cin
。
所以从如果条件,if(cin)
和if(cin >> x)
彼此相似。标准 IO库为此流定义了一个函数(取决于实现):
explicit operator bool() const; // C++11
或
operator void*() const; //C++98, C++2003
从这两个声明中,我们知道他们强制 流类型直接或间接(通过void*
pinter到bool
这很明显)到bool
类型。
在这两个函数中,它们依赖于一些基本的 IO steam 状态(类字段)来确定返回false还是true(对于void*
情况,它是nullptr
或不)。
cin
是类istream
的一个实例,它继承了 cast-to-bool 函数。所以它有效!
答案 6 :(得分:0)
因为cin是类的对象,请在http://www.cplusplus.com/reference/iostream/cin/上阅读更多内容。
答案 7 :(得分:0)
据我所知,重载运算符>>返回类istream的对象。这就是为什么这里没有不同的
答案 8 :(得分:0)
1)cin
是istream
的一个实例,请参阅http://www.cplusplus.com/reference/iostream/cin/。
2)>>
的{{1}}运算符将返回其左操作数,在本例中为istream
,请参阅http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/。如果没有从cin
中提取字符,此运算符将设置为failbit
,以防读者完成cin
,因此将不再有字符可供阅读。
3)截至上述2),在阅读操作后评估条件时,EOF
应该与if (cin >> x)
类似,请参阅此链接http://www.cplusplus.com/reference/ios/ios/operator_bool/您会看到,这个if (cin)
块将返回:
如果设置了if
或failbit
中的至少一个,则为空指针。否则为其他一些值(对于C ++ 98标准)。
如果设置了至少一个错误标志,则该函数返回false,否则返回true。 (适用于C ++ 11标准)
答案 9 :(得分:0)
std::cin
是std::istream
类的实例。
cin >> x
只是在cin
对象上调用一个函数。您可以直接调用该函数:
cin.operator >>(x);
为了使您可以一次读取多个变量,operator >>
函数返回对其调用的流的引用。您可以致电:
cin >> x >> y;
或等效地:
cin.operator >>(x).operator >>(y);
或:
std::istream& stream = cin.operator >>(x);
stream.operator >>(y);
难题的最后一部分是将std::istream
is convertible到bool
。布尔是
等同于调用!fail()
。
因此在以下代码中:
int x;
std::istream& stream = std::cin.operator >>(x);
bool readOK = !stream.fail();
if (readOK)
{
std::cout << x << "\n";
}
bool readOK = !stream.fail();
可以简化为bool readOK = stream;
。
您不需要单独的bool
来存储流状态,因此只需执行if (stream)
。
删除临时stream
变量将得到if (std::cin.operator >>(x))
。
直接使用运算符可以使我们回到原始代码:
int x;
if (std::cin >> x)
{
std::cout << x << "\n";
}