1

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

3 に答える 3

2

実際に要素を消去するには、次のようにする必要があります

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

remove_if要素が削除された範囲 (新しい終了) のみを提供します。そして、あなたのコードでは、あなたptrはまさに新しい終わりです(つまり、最後の有効な要素の1つ後)。

于 2012-01-18T15:14:43.533 に答える
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ドキュメントから

範囲 [first,last) 内の要素に pred を適用し、結果の範囲から false を返さない要素を削除します。結果の範囲は、 first と関数によって返されたイテレータの間の要素で構成され、範囲の新しい終了を指します。

削除されなかった要素の相対的な順序は保持されますが、値が指定されていない場合でも、範囲の新しい終了を過ぎた要素は引き続き有効です。

一般に、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)
    {
    }
于 2012-01-18T15:13:05.553 に答える
1

この行

ptr = &(*i);

シーケンスのフィルタリングされた部分の末尾の後の要素を逆参照しています。フィルタが要素とまったく一致せず、何も削除されなかった場合は、イテレータをベクトルの末尾の 1 つ後ろに逆参照しようとしています。これにより、報告されたエラーが発生します。が指し示す要素の内容は、iあまり役に立たない可能性があります。

あなたが何になりたいのかはまったく明確ではありませんptrが、これではないことは確かです.

于 2012-01-18T15:18:06.077 に答える