On Mon, 11 Oct 2004 10:19:54 -0600, David M. Jones
wrote:
- The container itself would act more or less identically to
std::list;
- The iterators on the container would act like boost::weak_ptr in
would know that they are invalid when the list element that they
"Caleb Epstein" wrote in message
news:<989aceac041012063240b6aa3@mail.gmail.com>...
that they
point to is
removed.
Can't you just do this with a std::listboost::shared_ptr? You can
convert the *iterators to weak_ptrs as needed. Or am I missing
something?
There are a couple of reasons that std::listboost::shared_ptr is less
than ideal.
First, using the algorithms becomes cumbersome/annoying. Instead of
being able to write
std::list lst;
// ... Populate the list
int i;
// ... Set the value of i
std::list::iterator = std::find(lst.begin(),
lst.end(), i);
I instead need to create a function object to represent a
boost::shared_ptr<int> having the desired value and then use find_if().
Second, I would lose the ability to store iterators and then check them
later for validity. Suppose that I have a
std::list
named lst and I have two std::list::iterator
objects it1 and it2 that happen to reference the same node in the list.
If I call
lst.erase(it1)
then it2 also becomes invalid. If I call
boost::weak_ptr<int>(*it2)
I get an error because I cannot dereference the iterator because it is
already invalid. This is how std::list objects are supposed to work but
what I want to be able to do is now call something like
it2.expired()
to determine that the node being refered to by it2 is not
invalid/expired/removed. One way to get around this is to store
boost::weak_ptr objects derived from
std::listboost::shared_ptr::iterator objects instead of storing it1
and it2 directly. But then I lose the advantage of having stored
iterators: I cannot (after checking for expiration and being at the end
of the list) call operator++() to move the iterator forward.
Fundamentally, I don't want to be storing a "list of nodes of shared
pointers of objects" but a "list of nodes of objects whose pointers to
each other are shared pointers". And I want the iterators to be weak
pointers to the nodes. Potentially a way to do this would be to write a
custom allocator my_alloc that declares
typedef boost::shared_ptr pointer;
and then create a
std::list
This works because std::list uses the allocator rebinding mechanism to
call my_alloc rather than my_alloc<T>. (In fact, my_alloc<T>
is never used to allocate anything in std::list<T>!) However, there is a
problem because the interface (concept a la Austern) of
boost::shared_ptr is different than that of a regular pointer. So when
the std::list code tries to call
_Myhead = 0;
I get a compiler error. (I am using MSVC 7.1: although this particular
error may be STL implementation dependent, I do believe that the problem
I am describing will occur with any STL implementation.) But I
digress... The question of why the boost::shared_ptr interface/concept
does not conform to that of a normal pointer is probably a topic for a
separate posting.