[C++-sig] Problem exposing container iterator with boost::iterator_adaptor

Mitch Jones mitch at niftyneato.com
Wed May 2 07:15:34 CEST 2007

on 4/27/07 11:47 AM, Roman Yakovenko at roman.yakovenko at gmail.com scribbled:

> Your code looks correct, can you create small example, which reproduce
> the problem?

Well, the sample turned out to be 150 or so lines, and in the end I figured
out the problem as I was working with the sample.

> Also what happens if you replace
> .def("__iter__", range(&Container::begin, &Container::end)
> with
> .def("__iter__", range(&WidgetContainer::begin, &WidgetContainer::end)
> ?

This was a typo and should have read WidgetContainer all along.

The problem boiled down to how my iterator adaptor was declared which looked
something like 

class WidgetIterator : public iterator_façade<WidgetIterator,
shared_ptr<Widget>, single_pass_traversal_tag>

What would happen is that dereference would get called and the current item
would get passed back, but if you notice, the definition of the iterator
doesn't define the reference type, it uses the default, which is absolutely
not what you want in this case.

In this case, dereference looks like

shared_ptr<Widget> & dereference() const { return current;}

The shared_ptr never gets properly copied causing premature destruction
which leads to the "pure virtual method called" error.

So, in answer to my question "Is the iterator_adaptor a red herring and the
real issue in Widget and its descendants and I've missed something obvious?"
The answer was no and yes.

Mitch Jones                                 mitch at niftyneato.com

More information about the Cplusplus-sig mailing list