如何使用stl从容器集中删除自定义对象?

时间:2015-05-10 06:16:35

标签: c++ stl set remove-if

以下是类和容器

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

如何从具有某个名称=&#34; suri&#34;;

的集合中删除对象

我做了什么?

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

但我收到编译时错误 错误2错误C3892:&#39; _Next&#39; :你不能分配给const c:\ program files(x86)\ microsoft visual studio 10.0 \ vc \ include \ algorithm 1816

的变量

我做错了什么? 如何使用stl从容器集中删除自定义对象?

3 个答案:

答案 0 :(得分:3)

enter image description here

如果你看一下*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;
    }
}

答案 1 :(得分:1)

正如@pola sai ram指出的那样,你不能起诉std::remove,因为这需要elemetns可以分配。

但是,您不需要删除
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"));
}

答案 2 :(得分:0)

此类算法已proposed并已添加至Library Fundamentals 2 TS。如果您的编译器支持Library Fundamentals 2 TS,您可以#include <experimental/set>并使用std::experimetal::erase_if(s, nameIs("suri"))