istream (ostream)与bool的区别

6

这里是一段C++代码,它会从给定的文本文件中尽可能读取更多单词,直到遇到EOF。

string text;
fstream inputStream;


inputStream.open("filename.txt");

while (inputStream >> text)
    cout << text << endl;

inputStream.close();

我的问题是:
- 将 while 循环的条件(即 inputStream >> text)转换为布尔值(true 或 false)时,实际上执行了什么过程?
我的回答是:
据我了解,inputStream >> text 应该返回另一个(文件)输入流。当 EOF 到达时,该流似乎为 NULL。NULL 可以被定义为 0,这相当于 false。
我的回答有意义吗?即使我的回答有意义,将 InputStream 转换为布尔值也不会让我感到很舒服。 :)

在 C 和 C++ 代码中,你会看到这种检查非空和非零的习惯用法。人们很快就会习惯读取 beerBottles = 99; while(beerBottles) beerBottles--; 的代码。 - RobP
原因是为了让你可以做像 cin >> x >> y; 这样的事情。如果 operator>> 返回一个布尔值,那将是不可能的,但是 nullptr(或在这种情况下的隐式转换为布尔值)将被评估为 false,所以双赢。 - Ed S.
2个回答

12

当将 while 循环的条件(即 inputStream >> text)转换为布尔值(即 true 或 false)时,实际上执行了什么过程?

operator>> 返回一个指向流的引用。

在 C++11 中,该引用随后通过流的 operator bool() 函数转换为 bool,该函数返回等效于 !fail() 的值。

在 C++98 中,可以使用 operator void*() 来实现相同的功能,返回的指针要么是 NULL 表示失败,要么是非空指针(如果 fail() 为假),然后在 while 的评估中隐式转换为 bool


你的回答完全符合我在帖子上的期望。谢谢! - user3509406
5
提醒OP一下:在C++11之前使用operator void*()的原因是为了避免一些可疑的代码被意外编译,例如让每个流对象产生一个bool值,然后将这些值进一步转换为整数(true->1,false->0)进行可能不被预期的整数操作,如stream1 << stream2stream1 + stream2。C++11引入了explicit operator bool() - 这种新的用法支持explicit修饰符,可以限制在布尔上下文之外的类型转换。 void*并不完全奏效- stream1 < stream2仍然是合法的,但explicit也能解决这个问题。 - Tony Delroy
2
如果这个答案解决了你的问题,请点击左边的绿色勾号接受它。 - HolyBlackCat

0

我知道我的问题已经被user657267完美地回答了。但是我想再添加一个例子来更容易地理解答案。

// evaluating a stream
#include <iostream>     // std::cerr
#include <fstream>      // std::ifstream

int main () {
  std::ifstream is;
  is.open ("test.txt");
  if (is) {           <===== Here, an example of converting ifstream into bool
    // read file
  }
  else {
    std::cerr << "Error opening 'test.txt'\n";
  }
  return 0;
}

参考 http://www.cplusplus.com/reference/ios/ios/operator_bool/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接