Removing or just finding a member in a ptr_list by address is not immediately possible:
boost::ptr_list<int> l; int *a = new int(7); int *b = new int(7); l.push_back(a); l.push_back(b); // The obvious thing to try is remove, which doesn't compile: // l.remove(a); // error // l.remove(*a); // error // The following compiles, but searches using int::operator== // instead of pointer equality, which results in finding a and not b. boost::ptr_list<int>::iterator it = find(l.begin(), l.end(), *b); l.erase(it); // erase a
Obviously, if the contained type doesn't have operator==, it doesn't even compile:
struct A {};
boost::ptr_list<A> l;
A *a = new A;
l.push_back(a);
// Doesn't compile, because A has no operator==
// boost::ptr_list<A>::iterator it = find(l.begin(), l.end(), *a); // error
Define a new algorithm that searches using pointer equality:
// Returns an iterator pointing to the first element of pointer container that has the same
// address as ptr.
// For some mind-boggling reason, neither ptr_list<A>::remove(A *ptr)
// or find(begin, end, A *ptr) works with ptr_list.
template<
typename Ptr_container_iterator,
typename Value_type
>
Ptr_container_iterator find_ptr(
Ptr_container_iterator begin, Ptr_container_iterator end,
Value_type *ptr) {
Ptr_container_iterator i;
for(i = begin; i != end; ++i) {
if(&(*i) == ptr) break; // compare by address
}
return i;
}
And use it:
struct A {};
boost::ptr_list<A> l;
A *a = new A;
l.push_back(a);
boost::ptr_list<A>::iterator it = find_ptr(l.begin(), l.end(), *a);
l.erase(it);