Remove item 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?
Clients receive new instance reader objects from the dispatcher / dispatcher. The manager maintains an internal list of all sent and invalid / frees cached data if "all interested" raised it by watching the pool of sent readers.
When the client is no longer interested in the data, it must return the reader to the manager for removal from the pool. But I donβt want the client to keep the iterator β he had absolutely no interest in the manager guts and the reader pool; it only needs that own reader, not an iterator pointing to it. So, to remove it, it calls the manager's cleanup function, referencing that single reader.
Is there a better way to erase this reader from the list than to iterate over the entire list looking for that one reader that the link leads to?
source to share
Your parameters, if you only have an object reference, should use std::list::remove
readers.remove(r);
or std::find
in combination withstd::list::erase
readers.erase(std::find(readers.begin(), readers.end(), r));
The former should iterate over the entire list, while the latter will stop when it finds the first element and then remove it. For a large list, this can make a big difference.
Both of these options only work when items are unique. If you have unique elements, you can use std::find_if
and provide a functor that compares the address of the elements. This way you can ensure that you are only deleting the referenced object and not being compared to an equal.
readers.erase(std::find_if(readers.begin(), readers.end(), [&](const auto& e) {return &r == &e;}));
source to share
Use std::remove
in conjunction witherase
readers.erase(std::remove(readers.begin(), readers.end(), r), readers.end());
Also, u cannot remove an item from the list by value without iterating over it. If you think about it, it doesn't even make sense, because the pointers inside the list must be updated .
source to share
If the list can contain equal values, you can do something like the following
#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;
}
Program output
A 1
A 3
source to share