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

Roman Yakovenko roman.yakovenko at gmail.com
Fri Apr 27 20:47:11 CEST 2007


On 4/26/07, Mitch Jones <mitch at niftyneato.com> wrote:
> I've been experimenting with the boost::python library and slowly getting
> the hang of it, although I've run into a problem I don't quite understand.
>
> I have a container class that provides begin and end functions that are
> implemented with the help of boost::iterator_adaptor. The iterator is
> forward only.
>
> This class and the thing it contains is then exported to python via
> boost::python.
>
> A snippet of the definitions I have:
>
> class_<BaseWidget, shared_ptr<BaseWidget> >("BaseWidget", no_init)
>    .def("__repr__", &Widget::name);
> class_<BigWidget, bases<BaseWidget>("BigWidget", no_init);
> class_<LittleWidget, bases<BaseWidget>(" LittleWidget", no_init);
>
> class_<vector<Widget> >("Widgets", no_init)
> .def(vector_indexing_suite<vector<Widget>, true>());
>
> class_<WidgetContainer, shared_ptr<WidgetContainer>, noncopyable >("
> WidgetContainer", no_init)
> .def("__iter__", range(&Container::begin, &Container::end) //the iterator
> returns shared_ptr<Widget>
> .def("contents", &WidgetContainer::contents); //returns vector<Widget>
>
> When used in python, I get a "pure virtual method called" error followed by
> a terminate/abort when I try to iterate over WidgetContainer.
>
> widgets = container_factory() # factory that supplies a WidgetContainer
>
> for some_widget in widgets :
>     print some_widget
>
> If I ignore iteration and instead return a list, I have no problem:
>
> for some_widget in widgets.contents():
>     print some_widget
>
> Is there some more scaffolding I still need to define to support iteration?
> It's not really clear to me what the error really means. The Widget base
> class has no virtual functions other than it's destructor. Is it referring
> to the iterator_adaptor? Does the iterator_adaptor class need to be exposed
> to python? Is the iterator_adaptor a red herring and the real issue in
> Widget and its descendants and I've missed something obvious?

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

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

-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/



More information about the Cplusplus-sig mailing list