2

以下はクラスとコンテナです

class student {
    std::string name;
    int id;
}

set<Student*, compare> s; // sorted by id that i have done correctly
class compare {
public:
    bool operator()( Student* s1, Student* s2) {
        return s1->id < s2->id;
    }
};

いくつかの名前を持つセットからオブジェクトを削除する方法 = "suri";

私がしたこと?

std::remove(s.begin(), s.end(), nameIs("suri"));

関手は

struct nameIs {
    nameIs ( std::string s ) : toFind(s) { }
    bool operator() ( Student* st)
    { return st->name.compare(toFind) == 0; }
    std::string toFind;
};

しかし、コンパイル時エラー Error 2 error C3892: '_Next' : you cannot assign to a variable that is const c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm 1816 が発生します

私は何を間違っていますか?stl remove from container set を使用してカスタマイズされたオブジェクトを削除するには?

4

3 に答える 3

3

ここに画像の説明を入力

あなたがそれを見れば、*first == valしかし実際にあなたの場合、それは*first->name == val

まあ、あなたはこれを試すことができます

std::set<Student*>::iterator it = s.begin();
for (it = s.begin(); it != s.end(); ) {
     if ((*it)->name == "suri") {
        s.erase(it++);
         break;
    }
    else {
        ++it;
    }
}
于 2015-05-10T06:28:31.243 に答える
1

@pola sai ram が指摘したようにstd::remove、要素を割り当て可能にする必要があるため、訴えることはできません。

ただし、 removeは必要あり
std::removeません。コンテナーから要素を実際に削除するわけではなく、保持したいすべての要素を前面にコピーするだけです ( erase-remove-idiom を参照)。実際に削除するには、常にコンテナー固有のerase関数を使用する必要があります。したがって、あなたの場合はfind_if、の代わりに使用できますremove。欠点は、複数回呼び出す必要があることです。

auto it = std::find_if(begin(s), end(s), nameIs("suri"));
while (it != end(s)){
    it = s.erase(it);
    it = std::find_if(it, end(s), nameIs("suri"));
}
于 2015-05-10T09:48:18.020 に答える
0

そのようなアルゴリズムが提案され、 Library Fundamentals 2 TSに追加されました。コンパイラが Library Fundamentals 2 TS をサポートしている場合は#include <experimental/set>std::experimetal::erase_if(s, nameIs("suri")).

于 2015-05-10T08:52:56.590 に答える