如果(cin >> x) – 为什么你可以使用这种情况?

我一直在使用“加速C ++”在夏天学习C ++,并且有一个我似乎并没有正确理解的概念。

为什么是

int x; if (cin >> x){} 

相当于

 cin >> x; if (cin){} 

通过查看代码,在我看来,我们使用cin作为variables。 但是,我认为这是一个function。 为什么我们可以用这种方式使用cin,当x是我们input到键盘的任何值时?

cin是表示标准inputstream的类istream的对象。 它对应于cstdiostreamstdin 。 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::cinstd::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语句中可用的转换运算符。 它是语言用于iftesting的特定于版本的转换运算符。 由于读取失败将stream标记为无效,如果读取不起作用,则iftesting将失败。

在C ++ 11之前,更为复杂的operator void*转换成员的原因是,直到C ++ 11,已经存在的explicit关键字才被扩展以适用于转换运算符以及构造函数。 一个非明确的operator bool()将会给程序员提供太多的机会让自己在脚下自拍。 operator void*()也有问题。 “安全布尔成语”本来就是一个解决scheme,但是只是简单地扩展到完全安全的布尔成语,而不需要使用大量的SFINAE魔法。

cinistreamtypes的(全局)variables,不是函数。

istream类重写>>操作符来执行input并返回一个对你调用它的对象( cin )的引用。

cinstd命名空间中是可变的。

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 ,这是显而易见的)投入到booltypes中。

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

cin是类inheritance了cast-to-bool函数的istream一个实例。 所以它的作品!

因为cin是类的一个对象,请参阅http://www.cplusplus.com/reference/iostream/cin/

据我所知,重载操作符>>返回类istream的对象。 这就是为什么这里不是不同的

1) cinistream一个实例,请参阅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有一个failbitbadbit被设置, badbit空指针。 另有一些其他值(用于C ++ 98标准)。

  • 如果至less有一个错误标志被设置,则函数返回false,否则返回true。 (对于C ++ 11标准)