istream std::cin 如何修改自定义istream 缓冲区?

how does istream std::cin modifies custom istream buffer?

我正在阅读 C++ Practical Programming by Example by Andrew Koenig (Author),在 4.1.3 Reading homework grades 一章中,有这个片段:

istream& read_hw(istream& in, vector<double>& hw){
    //if(in){      /* HOW can be istream be used as bool in condition? -> commented out, this is not needed */     
        //hw.clear();     /*WHY to clear vector, when every instance is used only once? -> commented out, not needed*/

        double x;
        while(cin >> x)
            hw.push_back(x);

        //in.clear();      /* why to clear istream from error state, when if wrong value is passed, it is ignored anyway -> commented out*/ 
    //}      /* this is connected with the if-block */
    return in;    /*how is now in(istream) modified? where is binding between `std::cout` and `in`?? */
}

我有几个问题:

  1. return value : 为什么函数有 istream 类型作为 return 值? 为什么函数不无效?当该函数的唯一目的是填充向量时,它不必 return 任何值。 (本题与上一题相连,istream in 是如何修改的)

  2. if(in) :如评论中所述,我知道如果 std::basic_ios::good 根据文档,它可能具有 true 值,但是,参数中的 istream 是新实例,因此在调用 之前 不应有任何错误状态,因此 if 子句是多余的。

  3. hw.clear() :同样,不需要清除向量。这是一个新实例,之前在程序中无处填充,为什么要这样做?

  4. in.clear() : 这个真的很烦我。在非并行过程中这甚至是必不可少的吗?我可以想到一种情况,何时清除缓冲区,即发生 fatal 错误时,否则,当缓冲区本身处理错误时,我认为没有必要清除缓冲区 -> 错误值被传递(在这种情况下是其他值然后加倍)=> 缓冲区简单地忽略它,或者调用 EOF => 缓冲区将结束读取。缓冲区会处理这一切。

  5. 最后一个——std::coutin是怎么连接的?书中引述:

We don't know the details of how cin works, but presumably the library defines it as a data structure that stores everything the library needs to know about the state of our input file. Reading input from the standard input file changes the state of the file, so it should logically change the value of cin as well.

我可以想象 std::cin 缓冲区确实是从键盘单词输入修改的(由空格分隔),但是 std::coutin 之间的连接在哪里,有只有 while(cin >> x) 修改了 cin,但是 cin 如何知道将这些数据复制到另一个缓冲区 in 中?或者,当该函数的唯一目的是填充向量时, in 的目的是什么?我想它与 return 以某种方式现在“修改” in 有某种联系,但我无法真正看到这两个缓冲区之间的联系。

我知道这与上面的书有关,所以如果你没有看过它,你可能没有上下文,但有些问题不需要上下文。

// comments 是指原代码中我认为不需要的部分注释掉了,编译后仍然有效,所以确实不需要。

/**/ 解释了为什么我认为不需要

无论如何抱歉这些初学者问题,我的背景只有 c

  1. return value : Why does the function have istream type as return value? Why is not the function void?

函数类型肯定可以无效,你是对的。但是,返回 istream& 允许链接,如下所示:

std::string name;
read_hw(cin, gradevec) >> name; 

这将从 cin 收到的第一个非双精度值放入 name 变量。不可否认,这是一个人为的例子,不是最易读的,但它确实展示了它是如何工作的。

  1. if(in) : as in comments, I know it could have true value if std::basic_ios::good according to documentation, however, the istream in parameter is fresh instance

不,它不是一个新的实例,它是一个已经在函数外定义的引用(由istream& in中的符号&表示)。

  1. hw.clear() : again, there is no need to clear the vector. It is a fresh instance, it was nowhere populated before in the program, so why to do this?

同样,实际上它不是新实例,它是对预先存在的向量 (vector<double>&) 的引用。 C 没有这样的引用,它只有指针,所以 this answer 可以帮助你更好地理解发生了什么。

  1. in.clear() : this one is really bother me. Is this even essential to do in non-parallel process? I can think of one case when to clear buffer and that is when fatal error occur.

in.clear() 有点令人困惑,它并没有清除整个缓冲区,它只是 clears the various state flagsfailbitbadbit 你不想留下来导致未来 I/O 操作失败。

  1. The last one - how is std::cout connected with in?

这个我只能猜测作者写错了,本意是while(in >> x)。否则根本没有必要使用 in