c++ - 为什么从分配给变量的 istream_iterator 读取不起作用?
问题描述
我编写了以下程序,它从 中读取 3 个数字std::cin
,并将它们输出到std::cout
,并执行两次:
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
std::copy_n(std::istream_iterator<int>(std::cin),
3,
std::ostream_iterator<int>(std::cout, " "));
std::copy_n(std::istream_iterator<int>(std::cin),
3,
std::ostream_iterator<int>(std::cout, " "));
}
对于 的输入1 2 3 4 5 6
,程序会打印预期的1 2 3 4 5 6
。
当我发现代码有点冗长时,我尝试将迭代器存储在变量中:
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
auto ins = std::istream_iterator<int>(std::cin);
auto outs = std::ostream_iterator<int>(std::cout, " ");
std::copy_n(ins, 3, outs);
std::copy_n(ins, 3, outs);
}
但现在对于输入1 2 3 4 5 6
,程序会打印 1 2 3 1 4 5
。
我不明白输出。这里发生了什么,我做错了什么?
另外,请注意,它仅在我使用ins
. 我是否使用outs
不影响输出。
解决方案
根据此参考:
std::istream_iterator 是单通道输入迭代器,通过调用适当的运算符>>,从为其构造它的 std::basic_istream 对象读取类型 T 的连续对象。实际的读取操作是在迭代器递增时执行的,而不是在取消引用时执行的。构造迭代器时读取第一个对象。取消引用仅返回最近读取的对象的副本。
因此,当您第一次创建ins
变量时,它会立即读取1
并cin
缓存它。
如果查看 的声明,输入迭代器是按值copy_n()
传递的,这意味着它是被复制的。
template< class InputIt, class Size, class OutputIt >
OutputIt copy_n( InputIt first, Size count, OutputIt result );
为了论证的缘故,我们假设copy_n()
正在使用以下实现(检查编译器的实际实现):
template< class InputIt, class Size, class OutputIt>
OutputIt copy_n(InputIt first, Size count, OutputIt result)
{
if (count > 0) {
*result++ = *first;
for (Size i = 1; i < count; ++i) {
*result++ = *++first;
}
}
return result;
}
当您传递ins
给copy_n()
时,该缓存1
被复制到first
参数中。copy_n()
取消引用时first
,它接收缓存1
并输出到result
. 然后copy_n()
递增first
读取2
并cin
缓存它,然后取消引用first
以接收2
和输出它,然后递增first
读取3
并cin
缓存它,然后取消引用first
以接收3
和输出它,然后退出。
当你再次传递ins
到copy_n()
时,原来的缓存1
还在ins
并被复制到first
参数中。copy_n()
取消引用时first
,它接收缓存1
并输出到result
. 然后copy_n()
递增first
读取4
并cin
缓存它,然后取消引用first
以接收4
和输出它,然后递增first
读取5
并cin
缓存它,然后取消引用first
以接收5
和输出它,然后退出。
推荐阅读
- linkedin - API请求分页响应错误
- c# - 异步方法不识别产量返回方法?
- python-3.x - Python pandas to_datetime 工作不一致:为什么月份和日期混在一起?
- git - 如何将分支与已发布的代码合并?
- scala - Scala解析器与List左递归
- c++ - JNI 错误:java.lang.NoSuchMethodError:没有静态方法
- python - 无法从函数附加值
- angular - Angular中动态表单下拉控件中的默认零值设置
- rx-java - Hybris Charon Web 服务方法实现(具有 Observable 返回类型)是否开箱即用异步运行?
- angular - 将 mat-select 中的选定字段传递给 TS