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) );
}

      

+2


a source to share


2 answers


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) );

      

+4


a source


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.

0


a source







All Articles