I created the following pure test program to illustrate the question:
#include <iostream>
#include <iterator>
#include <algorithm>
int main() // Test program. Not for real life solution. Just for demonstrating the question
{
int odd{ 0 }, even{ 0 }, nValues{ 0 };
std::cout << "Check and count odd and even numbers\n\nHow many numbers to check? Enter a value: ";
std::cin >> nValues;
std::for_each_n(std::istream_iterator<int>(std::cin), nValues, [&](const int i) {if ((i % 2) == 0) ++even; else ++odd; });
std::cout << "\nYou entered '" << even << "' even values and '" << odd << "' odd values\n\n";
return 0;
}
If I enter n, then n+1 values will be read.
cppreference explains about the istream_iterator:
The actual read operation is performed when the iterator is incremented, not when it is dereferenced. The first object is read when the iterator is constructed. Dereferencing only returns a copy of the most recently read object.
If I want to use the std::istream_iterator together with std::for_each_n(), I guess that I run into the implementation problem of std::for_each_n(), which maybe implemented (I know that it is only an example) according to cppreference like
template<class InputIt, class Size, class UnaryFunction> InputIt for_each_n(InputIt first, Size n, UnaryFunction f) { for (Size i = 0; i < n; ++first, (void) ++i) { f(*first); } return first; }
So, in order to check if f() has been called n times, it increments i AND the input iterator first. This leads in my demo example to an additional read from std::cin. So, it can never work for my test program. std::copy_n() seems to be implemented differently. The following works, when I want to read n values from std::cin into a vector. Like
std::vector<int> v(3);std::copy_n(std::istream_iterator<int>(std::cin), 3, v.begin());
So, I wonder, why the different behavior? Can the combination of std::istream_iterator and std::for_each_n() ever work?
What is the alternative solution using the <algorithm> library?