[英]remove element from std::list by reference
std::list<Reader> readers;
readers.push_back(Reader());
Reader& r = *(readers.begin());
/* at this point, the exact place in list, where the reader was picked out, is forgotten.
Only 'r' shows which element of the list it is. */
readers.erase(r); //<---how to do this?
客户端从经理/调度程序获取新实例的“读者”对象。 管理器维护一个内部列表,其中包含已发送的任何内容,如果“感兴趣的每个人”通过观察调度的读者池来获取缓存的数据,则会使缓存的数据无效/释放。
当客户端不再对数据感兴趣时,它应该将读取器返回给管理器以从池中删除。 但我不希望客户端保留一个迭代器 - 它对管理者和读者池的胆量绝对不感兴趣; 它只需要这个自己的读者,而不是指向它的迭代器。 因此,对于删除,它会调用管理器的清理函数,并引用该单个读取器。
是否有更好的方法从列表中删除该阅读器,而不是遍历整个列表以搜索引用所引导的那个阅读器?
将std::remove
与erase
结合使用
readers.erase(std::remove(readers.begin(), readers.end(), r), readers.end());
此外,您不能通过值从列表中删除元素,而无需迭代它。 如果你仔细想想,它甚至没有任何意义,因为列表中的指针必须进行更新。
如果您只引用该对象,则您的选项是使用std::list::remove
readers.remove(r);
或std::find
与std::list::erase
结合使用
readers.erase(std::find(readers.begin(), readers.end(), r));
前者必须遍历整个列表,而后者在找到第一个元素时将停止,然后将其删除。 对于大型列表,这可以产生很大的不同。
这两个选项仅在项目唯一时才有效。 如果你有非唯一元素,那么你可以使用std::find_if
并提供一个比较项目地址的函子。 这样你就可以保证你只删除引用实际引用的对象而不是比较等于。
readers.erase(std::find_if(readers.begin(), readers.end(), [&](const auto& e) {return &r == &e;}));
您可以比较指针以检查它们是否是同一个对象
readers.remove_if([r=&r](auto& x){return &x==r;});
如果列表可以包含相等的值,那么您可以执行以下操作
#include <iostream>
#include <list>
int main()
{
struct Reader { std::pair<char, int> p; };
std::list<Reader> readers;
readers.push_back({{ 'A', 1 } });
readers.push_back({ { 'A', 2 } });
Reader &rr = readers.back();
readers.push_back({ { 'A', 3 } });
readers.remove_if([&rr](const Reader &r) { return &r == &rr; });
for (const auto &r : readers)
{
std::cout << r.p.first << ' ' << r.p.second << std::endl;
}
return 0;
}
程序输出是
A 1
A 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.