[英]Can I delete a item from std::list based on pointer value?
这段代码是即时编写的,请忽略语法错误(如有)。
std::list<MY_STRUCT> myList;
MY_STRUCT theStruct;
myList.push_back( theStruct );
myList.push_back( theStruct );
// assume I store the pointer of the last item (the 2nd item in this case).
MY_STRUCT * item2 = &myList.back();
// I added another item
myList.push_back( theStruct );
// now I want to delete item2 that I stored bases on its pointer.
// Can myList.remove_if(...) help if so how?
我想通过其指针删除列表中的中间项(假设我有指针值)。
我知道我可以遍历列表并查找此指针,但是有更好的方法吗? STL是否提供执行此操作的功能。在这种情况下,我可以使用remove_if()删除项目吗?
除了保留指向要删除的对象的指针外,为什么不保留迭代器呢?
std::list<MY_STRUCT>::iterator item2 = --mylist.end();
remove_if算法实际上并不删除任何内容,它只是转移内容。 它不知道迭代器指向的容器。 当然,注释中指出的std :: list成员函数remove_if完全不同。
当然, list::remove_if
使用您提供的任何条件。 例如
template <typename T>
struct AddressIs {
T *ptr;
AddressIs(T *ptr) : ptr(ptr) {}
bool operator()(const T &object) const {
return ptr == &object;
}
};
myList.remove_if(AddressIs<MY_STRUCT>(item2));
Mankarse的观点是很好的-如果您可以使用迭代器而不是指针来标识您感兴趣的项目,那么您就不必为此烦恼了。
还请注意,我们在此依赖的事实是list
项目的地址永远保持不变。 并非所有集合都如此,例如,当您调用push_back
时, vector
可能必须重定位所有数据。 如果是这样,则item2
不再指向您的中间项目。 每个集合记录哪些操作会使迭代器和/或对元素的引用无效。
您可以获取end
迭代器,确保它不是begin
,递减一以指向最后一个项目,然后再erase
该迭代器,而不是获取back
一项,然后在需要时直接erase
该迭代器。
我认为remove_if对于zadane想要做的事情有些过大。 所有需要完成的就是保存项目的位置或值,以便以后删除该特定项目。
如Mark所建议的,您可以将迭代器存储到对象,并使用它通过一次擦除调用删除该项目,如下所示:
MY_STRUCT struct;
myList.push_back(struct);
myList.push_back(struct);
std::list<MY_STRUCT>::iterator del_it = myList.end() - 1;
myList.erase(del_it);
或者,如果您的结构具有为MY_STRUCT定义的==运算符,则可以存储对象本身的值并使用remove方法
MY_STRUCT struct1;
MY_STRUCT struct2;
myList.push_back(struct1);
myList.push_back(struct2);
myList.remove(struct2);
当然,如果将列表作为指针列表,则不必担心==运算符,因为它已经为指针类型定义了。 只要确保您要遍历列表并调用擦除操作,就需要使用返回值更新迭代器。
另外,remove方法将删除传递的值的所有元素,因此,如果您一次只希望删除1个项目,请保存迭代器而不是值。
该代码未经测试,因此我欢迎进行任何更正。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.