I wrote the following program that reads in 3 numbers from std::cin
, and outputs them to std::cout
, and does this twice:
#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, " "));
}
For an input of 1 2 3 4 5 6
, the program prints the expected 1 2 3 4 5 6
.
As I found the code a bit verbose, I tried to store the iterators in variables:
#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);
}
But now for the input 1 2 3 4 5 6
, the program prints 1 2 3 1 4 5
.
I don't understand the output. What's going on here, and what am I doing wrong?
Also, note that it only matters when I use ins
. Whether I use outs
or not doesn't affect the output.
If you look at Defect Report P0738R2 you'll see the first read for an
istream_iterator
should be performed by the constructor, so it's reading1
at the lineauto ins = ...
.copy_n
takes its arguments by value, so the first invocation doesn't movemain()
sins
variable past the1
it has already read, and that's provided again to the second invocation ofcopy_n
.If you want concision, you could do something like: