Search code examples
c++pointersreferencedereferenceremove-if

C++ Regarding pointer/reference with remove_if


I'm trying to use remove_if to remove elements in my vector to do filtering. The problem is when I compile the coding, there were no error but when I try to use the filter function, error popped out saying I can't dereference an iterator. I have no idea what is wrong and hope you guys can help spot the problem. Here's partial of my codes

bool filter_C (Teacher &t) 
{ 
return (t.getCat() != compare); //compare is a static string
}
void filterTeacherCategory(vector<Teacher> &t)
{
    vector<Teacher>::iterator i;
    Teacher *ptr;
    i = remove_if(t.begin(), t.end(), filter_C);
    ptr = &(*i);
    for (i = t.begin(); i != t.end(); ++i)
    {
        ptr->getName();
        cout << "\t";
        ptr->getGender();
        cout << "\t";
        ptr->getPhone();
        cout << "\t";
        ptr->getCategory();
        cout << "\t\t";
        ptr->getLocation();
        cout << "\n";
     }
}

Solution

  • remove_if returns the new end of the vector. so you should be iterating like so

    vector<Teacher>::iterator i;
    vector<Teacher>::iterator newenditer = remove_if(..);
    
    
    for (i = t.begin(); i != newenditer ; ++i)
    {
           Teacher& tchr= *i;
           cout << tchr.getName() << "\n";
           cout << tchr.getPhone() << "\n";
    
    }
    

    From remove_if documenation

    Applies pred to the elements in the range [first,last), and removes those for which it does not return false from the resulting range. The resulting range consists of the elements between first and the iterator returned by the function, which points to the new end of the range.

    The relative order of the elements not removed is preserved, while the elements past the new end of range are still valid, although with unspecified values.

    In general it is a good idea to erase the remaining elements after a remove_if

    vector<Teacher>::iterator i;
    vector<Teacher>::iterator newenditer = remove_if(..);
    t.erase( newenditer , t.end() );
    

    Now everything between t.begin() and t.end() is all valid and good so you can do

     for (i = t.begin(); i != t.end() ; ++i)
        {
        }