Search code examples
c++iteratorg++stdvectormismatch

error: no match for 'operator=' for operand types std::vector::iterator and __gnu_cxx::__normal_iterator


I'm getting a very nasty error because apparently my iterator types don't match when I try to assign from find_if to a predefined iterator. I'm not using auto because I want to exclude definitions from the for-loop to avoid reallocation.

This is the error in essence:

../components/aurora_fsm/aurora_fsm.cpp: In member function 'FSM_StateBase* FSM_StateBase::FollowBits(EventBits_t)':
../components/aurora_fsm/aurora_fsm.cpp:43:118: error: no match for 'operator=' (operand types are 'std::vector<FSM_StateBase*>::iterator' {aka '__gnu_cxx::__normal_iterator<FSM_StateBase**, std::vector<FSM_StateBase*> >'} and '__gnu_cxx::__normal_iterator<FSM_StateBase* const*, std::vector<FSM_StateBase*> >')
             [&s_checked](FSM_StateBase* const state) { if (!s_checked.count(state)) { return true; } return false; } );

And this is my implementation of the method in question with just the relevant details:

FSM_StateBase* FSM_StateBase::FollowBits()
{
    std::vector<FSM_StateBase*> v_tmp_path = { this };
    std::unordered_set<FSM_StateBase*> s_checked;

    std::vector<FSM_StateBase*>::iterator it;

    for (;;) {
        // find new state that is not checked
        auto& v_adjacent = v_tmp_path.back()->GetAdjacentStates();
        it = std::find_if(begin(v_adjacent), end(v_adjacent), 
            [&s_checked](FSM_StateBase* const state) { if (!s_checked.count(state)) { return true; } return false; } );
        
        // ...
    }
    // ..
}

Yet I have no idea what to change to make this work? After all, find_if is supposed to return an iterator for a vector of the specified type (FSM_StateBase* in my case) which is exactly what I'm defining it to be..

EDIT (for clarity):

const std::vector<FSM_StateBase*>& FSM_StateBase::GetAdjacentStates(void) {
    return adjacent_states_;
}

with

class FSM_StateBase
{
protected:
    std::vector<FSM_StateBase*>             adjacent_states_;
    // ...
}

Solution

  • std::find_if will return the same type of iterator that was passed to it.

    v_adjacent will have the type const std::vector<FSM_StateBase*>&. Notice the const being part of the type. That const means the iterators for this container will be constant iterators.

    it, on the other hand, is not a constant iterator.


    There's a hint in the error message where it says that the left-hand side of the assignment (the variable it) is the type

    __gnu_cxx::__normal_iterator<FSM_StateBase**, std::vector<FSM_StateBase*> >
    

    And the type of the right-hand side of the assignment (what is returned by std::find_if) is

    __gnu_cxx::__normal_iterator<FSM_StateBase* const*, std::vector<FSM_StateBase*> >
    

    Notice the const in FSM_StateBase* const*.