My first steps with function templates
Thought it was pretty straight forward.
But when I run the code below, I get an "iterator not reversible".
What's wrong?
template<typename T>
struct SumsTo : public std::binary_function<T, T, bool>
{
int myInt;
SumsTo(int a)
{
myInt = a;
}
bool operator()(const T& l, const T& r)
{
cout << l << " + " << r;
if ((l + r) == myInt)
{
cout << " does add to " << myInt;
}
else
{
cout << " DOES NOT add to " << myInt;
}
return true;
}
};
void main()
{
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
list<int> l2;
l2.push_back(9);
l2.push_back(8);
l2.push_back(7);
l2.push_back(6);
transform(l1.begin(), l1.end(), l2.begin(), l2.end(), SumsTo<int>(10) );
}
a source to share
Your functor is fine. The problem is the challenge transform
.
The transformation has a prototype
transform(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _OutputIterator __result,
_BinaryOperation __binary_op)
your call
transform(l1.begin(), l1.end(), l2.begin(), l2.end(), SumsTo<int>(10) );
instead l2.end()
, the fourth argument of the iterator must be the start of the sequence of results. It should refer to a sequence of objects that you can build from bool
.
If you want to save the results to l2
, then you want
transform(l1.begin(), l1.end(), l2.begin(), l2.begin(), SumsTo<int>(10) );
As GMan suggests, a different approach std::back_inserter
from <iterator>
:
vector<bool> sums10; // vector<bool> is Good Enough for Me
transform(l1.begin(), l1.end(), l2.begin(), back_inserter(sums10), SumsTo<int>(10) );
a source to share
As Potatoswatter noted, transform
has a prototype
transform(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _OutputIterator __result,
_BinaryOperation __binary_op)
This means that the first two arguments indicate a range. In your casel1.begin(), l1.end()
The next argument is the starting point of the following list: l2.begin()
The fourth argument is where your problem lies. It asks for an "output" iterator or somewhere to put the result of your operation. Instead, you give it the end of the second list.
Try the following:
//...
list<bool> l3;
transform(l1.begin(), l1.end(), l2.begin(), back_inserter(l3), SumsTo<int>(10));
If it doesn't compile then try adding #include <iterator>
What it does back_inserter
is it creates an iterator that, when written (which makes it an "output" iterator), does it push_back
with the value it gave to the container you pass it to.
a source to share