gpt4 book ai didi

c++ - 为什么带有多个 copy_n() 的 std::istream_iterator<> 总是写入第一个值

转载 作者:行者123 更新时间:2023-12-01 14:20:07 26 4
gpt4 key购买 nike

我试图将输入行复制到多个 vector 中:

#include <vector>
#include <sstream>
#include <istream>
#include <iterator>
#include <algorithm>
#include <iostream>

int main(){
std::vector<int> v1, v2, v3;
std::istringstream is ("1 2 3 4 5 6");
std::istream_iterator<int> iit (is);
std::copy_n(iit, 2, std::back_inserter(v1));
std::copy_n(iit, 2, std::back_inserter(v2));
std::copy(iit, std::istream_iterator<int>(), std::back_inserter(v3));
std::ostream_iterator<int> oit(std::cout, ", ");
std::copy(v1.begin(),v1.end(), oit);
std::cout << "\n";
std::copy(v2.begin(),v2.end(), oit);
std::cout << "\n";
std::copy(v3.begin(),v3.end(), oit);
std::cout << "\n";
return 0;

}
我假设这个程序输出:
1, 2, 
3, 4,
5, 6,
但我明白了:
1, 2, 
1, 3,
1, 4, 5, 6,
为什么 copy_n 总是在 vector 开头插入 1?

最佳答案

这归结为 istream_iterator 的一个可能不直观的事实。 :当您取消引用它时它不会读取,而是 when you advance (or construct) it .

(x indicates a read)

Normal forward iterators:

Data: 1 2 3 (EOF)

Construction
*it x
++it
*it x
++it
*it x
++it (`it` is now the one-past-the-end iterator)
Destruction

Stream iterators:

Data: 1 2 3 (EOF)

Construction x
*it
++it x
*it
++it x
*it
++it (`it` is now the one-past-the-end iterator)
Destruction
我们仍然希望通过 *it 向我们提供数据。 .所以,为了使这个工作,读取数据的每一位都必须临时存储在迭代器本身中,直到我们下一步做 *it .
因此,当您创建 iit 时,它已经为你拉出第一个号码, 1 .该数据存储在迭代器中。流中的下一个可用数据是 2 ,然后您可以使用 copy_n 将其拉出.总共提供了两条信息,在您要求的总共两条信息中,所以第一个 copy_n已经完成了。
下一次,您将使用 iit 的拷贝在第一次之前的状态 copy_n .所以,虽然流已经准备好给你 3 ,你还有一份 1 “卡在”你复制的流迭代器中。

为什么要使用流迭代器 work this way ?因为在您尝试并未能获得更多数据之前,您无法检测流上的 EOF。如果这种方式不起作用,您必须首先进行取消引用以触发此检测,然后如果我们达到 EOF,结果应该是什么?
此外,我们希望任何取消引用操作都会立即产生结果;使用给定的容器,但使用流,您可能会阻塞等待数据可用。相反,在构造/增量上执行此阻塞更合乎逻辑,以便您的迭代器始终有效或无效。

如果你解雇拷贝,并为每个 copy_n 构建一个新的流迭代器,你应该没问题。虽然我通常建议每个流只使用一个流迭代器,因为这样可以避免任何人担心这一点。

关于c++ - 为什么带有多个 copy_n() 的 std::istream_iterator<> 总是写入第一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62940748/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com