Reputation: 9
1) How can I pass a different value than end-of-stream to functions like find_if()
, sort()
, or for_each()
?
I don't manage to handle iterators, especially to use them in loops, it seems the way I try to browse the values is improper. What I'm trying to do with this code is to input some numbers with cin
, to extract the even numbers with find_if
, but to print the first three with for_each
or any loop using those iterators. If I use another kind, there would be no purpose.
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
typedef istream_iterator<int> IIT;
int main()
{
IIT iter(cin);
IIT eos;
auto even = [](int i){ return (i%2==0); };
iter = find_if(iter, eos, even);
//iter = find_if(iter, IIT(), even); //also works, it seems that ctor call of "IIT eof()" wasn't equivalent
//auto print = [](IIT i){ cout << *i << " "; };
//auto print = [](IIT i){ cout << *i << " "; return i; };
//auto print = [](IIT i){ cout << *i << " "; return 0; }; //I don't know what I'm doing
auto print = [](IIT i)->int { cout << *i << " "; return 0; }; //this doesn't help
for_each(iter,eos,print); //no match for call to '(main()::<lambda(IIT)>) (const int&)'|
for_each<IIT,IIT>(iter,eos,print); //no matching function for call to 'for_each(IIT&, IIT&, main()::<lambda(IIT)>&)'|
//cannot convert 'print' (type 'main()::<lambda(IIT)>') to type 'std::istream_iterator<int>'|
for(auto i : iter) cout << *i << " "; //candidate: template<class _Tp, unsigned int _Nm> constexpr _Tp* std::begin(_Tp (&)[_Nm])|
//template argument deduction/substitution failed:|
//mismatched types '_Tp [_Nm]' and 'std::istream_iterator<int>'|
return 0;
}
The default-constructed std::istream_iterator is known as the end-of-stream iterator. When a valid std::istream_iterator reaches the end of the underlying stream, it becomes equal to the end-of-stream iterator.
istream_iterator : default constructor
Constructs an end-of-stream istream iterator." [..] This kind of iterator has a special state as an end-of-stream iterator, which is acquired if an input operations fails (as returned by fail after an operation with the associated stream), and is also the resulting value of a default-constructed object.
stl_algo.h
template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__f(*__first);
return _GLIBCXX_MOVE(__f);
}
Upvotes: 1
Views: 222
Reputation: 41220
std::for_each
has template arguments template< class InputIt, class UnaryFunction >
You are calling it like so: for_each<IIT, IIT>
.
Change this to for_each<IIT, decltype(print)>
if you wish to use explicit template arguments (although I recommend letting the compiler infer the args via the parameters)
Your print
function is accepting an IIT
, when in fact algorithms will dereference the iterators passed to it for the unary function, so it should accept an int
instead:
auto print = [](int i)->int { cout << i << " "; return 0; };
for(auto i : iter)
makes no sense; iter
is an iterator type, not a range.
Upvotes: 0