如果(cin >> x) – 为什么你可以使用这种情况?
我一直在使用“加速C ++”在夏天学习C ++,并且有一个我似乎并没有正确理解的概念。
为什么是
int x; if (cin >> x){}
相当于
cin >> x; if (cin){}
通过查看代码,在我看来,我们使用cin作为variables。 但是,我认为这是一个function。 为什么我们可以用这种方式使用cin,当x是我们input到键盘的任何值时?
cin
是表示标准inputstream的类istream
的对象。 它对应于cstdio
streamstdin
。 stream的操作符>>
重载返回对同一个stream的引用。 stream本身可以通过转换运算符在布尔条件中评估为true或false。
cin
提供格式化的stream提取。 操作cin >> x;
如果input非数字值,那么“x”是一个int将失败。 所以:
if(cin>>x)
如果input一个字母而不是一个数字,将会返回false
。
关于使用C ++ I / O的技巧和窍门的网站也会帮助你。
注意:答案在事实发生四年后更新,以解决C ++ 98/03和C ++ 11(及更高版本)的问题。
std::cin
是std::istream
一个实例。 这个类提供了两个与这个问题有关的重载。
- 如果可能,
operator >>
将数据从stream中读入目标variables。 如果stream的直接内容不能被翻译成目标variables的types,则该stream被标记为无效,并且目标variables保持不变。 无论操作是成功还是失败,返回值都是对stream的引用。 - 无论是
operator void*()
(pre-C ++ 11),它将stream引用转换为void*
指针,或explicit operator bool()
(C ++ 11),将stream引用转换为布尔值。 如果stream是有效的,则该转换的结果是非空指针(pre-C ++ 11)或true
(C ++ 11),但空指针(pre-C ++ 11)或false
(C + +11)如果stream是无效的。
if
语句需要一个布尔值,一个整数或一个指针作为要testing的数量。 std::cin >> x
的结果是对istream
的引用,它不是以上所述。 但是, istream
类具有可用于将istream
引用转换为if
语句中可用的转换运算符。 它是语言用于if
testing的特定于版本的转换运算符。 由于读取失败将stream标记为无效,如果读取不起作用,则if
testing将失败。
在C ++ 11之前,更为复杂的operator void*
转换成员的原因是,直到C ++ 11,已经存在的explicit
关键字才被扩展以适用于转换运算符以及构造函数。 一个非明确的operator bool()
将会给程序员提供太多的机会让自己在脚下自拍。 operator void*()
也有问题。 “安全布尔成语”本来就是一个解决scheme,但是只是简单地扩展到完全安全的布尔成语,而不需要使用大量的SFINAE魔法。
cin
是istream
types的(全局)variables,不是函数。
istream
类重写>>
操作符来执行input并返回一个对你调用它的对象( cin
)的引用。
cin
在std
命名空间中是可变的。
operator>>
返回引用cin
,因为它可以写: cin >> a >> b
,而不是cin >> a; cin >> b;
cin >> a; cin >> b;
因为expression的结果
cin >> x
评估
cin
在stream被读取之后。
上面的答案是信息。 这里我只是给出一个额外的评论。
std::cin
是类istream
一个对象,表示与C stream中 stdin
对应的标准inputstream (即键盘)。
cin >> x
将首先从标准inputstream中读取一个int并将其赋值给x
。 之后,返回一个自我参考。 所以函数调用cin >> x
的返回值仍然是cin
。
所以从条件的angular度来看, if(cin)
和if(cin >> x)
彼此相似。 标准的IO库为这个stream定义了一个函数(取决于实现):
explicit operator bool() const; // C++11
要么
operator void*() const; //C++98, C++2003
从这两个声明中,我们知道他们直接或间接地将streamtypes (通过void*
pinter到bool
,这是显而易见的)投入到bool
types中。
在这两个函数中,它们依赖于一些基本的IO蒸汽状态(类字段)来确定是否返回false或true(对于void*
情况,它是否为nullptr
)。
cin
是类inheritance了cast-to-bool函数的istream
一个实例。 所以它的作品!
因为cin是类的一个对象,请参阅http://www.cplusplus.com/reference/iostream/cin/ 。
据我所知,重载操作符>>返回类istream的对象。 这就是为什么这里不是不同的
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
,以防止读取器完成EOF
这样就不会有更多字符可读。
3)在上述2)中,在读取操作后对条件进行评估时, if (cin >> x)
应该if (cin)
,请参考此链接http://www.cplusplus.com/reference/ ios / ios / operator_bool /你会看到, if
块将返回:
-
如果至less有一个
failbit
或badbit
被设置,badbit
空指针。 另有一些其他值(用于C ++ 98标准)。 -
如果至less有一个错误标志被设置,则函数返回false,否则返回true。 (对于C ++ 11标准)