if(cin>> x) - 为什么你可以使用这个条件?

时间:2011-07-22 14:29:25

标签: c++ variables if-statement cin

我在夏天一直使用“Accelerated C ++”来学习C ++,并且有一个我似乎无法理解的概念。

为什么

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

相当于

cin >> x;
if (cin){}

通过查看代码,在我看来,我们使用cin作为变量。但是,我认为这是一个功能。为什么我们能以这种方式使用cin,因为它是x,它具有我们输入键盘的任何值?

10 个答案:

答案 0 :(得分:59)

cin是类istream的对象,表示标准输入流。它对应于cstdiostdin。流的运算符>>重载返回对同一流的引用。通过转换运算符,可以在布尔条件下将流本身评估为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::cinstd::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)

cinistream类型的(全局)变量,而不是函数。

istream类会覆盖>>运算符以执行输入并返回对您调用它的对象的引用(cin)。

答案 3 :(得分:6)

cinstd命名空间中是变量。

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)cinistream的一个实例,请参阅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)块将返回:

  • 如果设置了iffailbit中的至少一个,则为空指针。否则为其他一些值(对于C ++ 98标准)。

  • 如果设置了至少一个错误标志,则该函数返回false,否则返回true。 (适用于C ++ 11标准)

答案 9 :(得分:0)

std::cinstd::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 convertiblebool。布尔是 等同于调用!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";
}