2012-01-18 8 views
1

Я пытаюсь использовать remove_if для удаления элементов в моем векторе для фильтрации. Проблема в том, что когда я компилирую кодировку, ошибок не было, но когда я пытаюсь использовать функцию фильтра, выдается ошибка, говоря, что я не могу разыменовать итератор. Я не знаю, что не так, и надеюсь, что вы, ребята, можете помочь решить проблему. Вот частичный из моих кодовC++ Что касается указателя/ссылки с remove_if

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

ответ

1

remove_if возвращает новый конец вектора. так что вы должны быть итерация, как так

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

} 

От remove_if documenation

Применяется ПРЕД к элементам в диапазоне [первый, последний), и удаляет те, для которых он не возвращает ложь от результирующий диапазон. Результирующий диапазон состоит из элементов между первым и итератором, возвращаемым функцией, которая указывает на новый конец диапазона.

Относительный порядок элементов, которые не удалены, сохраняется, а элементы, находящиеся за новым концом диапазона, остаются в силе, хотя и с неопределенными значениями.

В целом это хорошая идея, чтобы удалить оставшиеся элементы после remove_if

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

Теперь все между t.begin() и t.end() все действует и хорошо, так что вы можете сделать

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

так что мне еще нужно использовать указатель? – delphi316

+0

см. Мое редактирование –

+0

Это сработало, но теперь у меня есть еще одна проблема. Есть ли способ превратить remove_if в нечто вроде remove_ifnot? Я знаю, что этот звук выглядит забавным ... – delphi316

2

чтобы действительно удалить элементы, что вам нужно сделать что-то вроде

t.erase(std::remove_if(...),t.end()); 

remove_if предоставляет только диапазон (новый конец) с удаленными элементами. И в вашем коде ваш ptr - это точно новый конец (то есть один за последним действительным элементом).

1

Эта линия

ptr = &(*i); 

является разыменование элемента после окончания отфильтрованной части последовательности. Если ваш фильтр не соответствовал каким-либо элементам, поэтому ничего не удалялось, тогда вы пытаетесь разыменовать итератор до конца вектора, который даст сообщение об ошибке. И даже если содержимое элемента, на которое указывает i, вряд ли будет очень полезно.

Это не совсем понятно, что вы хотите ptr быть, но я уверен, что это не так.

+0

Думаю, вы поняли это правильно; приведенный выше код неверен, только если ничего не было «удалено», в противном случае он совершенно корректен (хотя, возможно, и неправильный), чтобы взять указатель на первый элемент * remove *. Однако, если ничего не было удалено, то, как вы правильно отметите, это потребует разыменования элемента * one-last-last *, который, конечно, недействителен. – bronekk

+0

Поскольку параметр фильтрации задается системой, которая берется из объектов в векторе – delphi316

 Смежные вопросы

  • Нет связанных вопросов^_^