通过引用从std :: list中删除元素
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 :: list中删除元素
当客户端不再对数据感兴趣时,它应该将读取器返回给管理器以从池中移除。但我不希望客户保留一个迭代器 - 它对经理和读者群的胆量绝对不感兴趣;只需要这个自己的读者,而不是指向它的迭代器。因此,对于删除,它会调用管理器的清除功能,并引用该单个阅读器。
是否有更好的方法从列表中删除该阅读器,而不是遍历整个列表以搜索参考导致的那个阅读器?
你的选择,如果你只需要对对象的引用是使用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;}));
使用std::remove
结合erase
readers.erase(std::remove(readers.begin(), readers.end(), r), readers.end());
而且,你无法从列表中删除价值元素,不反复它。如果你仔细想想,它甚至没有什么意义,因为列表中的指针必须更新为。
'remove'实际上在这种情况下被删除,因此无法编译,因为它返回'void'。 – NathanOliver
这不会找到正是这个元素,但任何元素是平等可比的...你必须比较elems指针... – ovanes
是的弥恩,我的坏,我更新了答案 –
你可以比较指针,以检查它们是否相同的对象
readers.remove_if([r=&r](auto& x){return &x==r;});
删除期望一个值,它可以比较列表中的项目。很确定这不会编译 – NathanOliver
也许你的意思是'remove_if'而不是'remove'? – Akira
更改'remove'到'remove_if',你有最酷的解决方案! – ovanes
如果列表中可以包含相同的值,那么你可以这样做以下
#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
是t hese'读者'唯一(没有'读者'具有相同的值)? – NathanOliver
@NathanOliver:是的。每个客户端都有一个独特的阅读器,通过方法从缓存中选择数据(并将其标记为“已被此用户使用”),如果所有感兴趣的用户都“用完了”,那么经理会使数据无效。 –
'readers.remove(r);'应该工作(如果'r'是唯一的),但会内部迭代列表。 –