zissler
zissler

Reputation: 117

How to use transform with a vector using the before and after values

So I was trying to find the average of all the values to the left and right of the iterator into a new vector. I was thinking of something like :

transform(begin(vector1)+1,end(vector2)-1, back_inserter           
(vector2),[](vector<int>::iterator n) {return (*(n - 1) + *(n) + *      
(n+1))/3;});

Unfortunately this gives me an error about convert argument from 1 'int' to std::vector_iterator

I'm declaring the parameter as a vector iterator, but I must be doing something wrong. I need to do this in either lambda or in using something in functional. I would like a point in the right direction of how to do this at the very least, since it's a pain to try and search the answer for this. Maybe if this has been asked before you can teach me what to type in to find an answer like this.

Upvotes: 0

Views: 83

Answers (2)

James Kanze
James Kanze

Reputation: 153919

std::transform is rather limited, in that it is designed to implement a bijection—a simple one-to-one translation. The function will be called with exactly one argument, the value currently under the iterator, and must always return exactly one element.

It is possible for the functional object to have state, but you have to be careful, since it has value semantics, and can and will be copied. You might try something like this, however:

class Smoother
{
    std::vector<int>* m_previous;
public:
    Smoother( std::vector<int>& previous )
        : m_previous( previous )
    {
    }

    int operator()( int next )
    {
        int results = std::accumulate( m_previous->begin(), m_previous->end(), next ) / (m_previous->size() + 1);
        m_previous->erase( m_previous->begin() );
        m_previous->push_back( next );
        return retval;
    }
};

You then first initialize a vector with the starter values, something like:

std::vector<int> tmp( vector1.begin(), vector1.begin() + 2 );
std::transform( vector1.begin() + 2, vector1.end(), std::back_inserter( vector2 ), Smoother( tmp ) );

Obviously, something like Smoother could be a template, and you could wrap the whole thing nicely in a function. (And even more obviously, if you did so, you'd want a bit more error checking.)

Upvotes: 1

Wojtek Surowka
Wojtek Surowka

Reputation: 20993

The argument should be the vector's value_type (or convertible to it, like const reference), so it should be int.

Upvotes: 1

Related Questions