Using iterator_facade from base class with sub classes

Hello! I have implemented the iterator_facade for a base class called DataObject. So now I am able to write things like this: boost::shared_ptr<PxyFileData> file(...); const DataObject& points = file->GetPoints(); int num_points = std::distance(points.begin(), points.end()); //! random access iterator A DataObject acts like a tree structure. Each DataObject holds a vector of pointers to children, which are also DataObjects. Now to my problem: A PxyPoint is a sub class to DataObject, and PxyFileData::GetPoints() returns a DataObject where all the children are PxyPoint's. Now I would like to call a member function, PxyPoint::PutSpCode(const char*), on each of the children, like this: void put_sp_code(DataObject&, const char*); void test() { shared_ptr<PxyFileData> file(...); DataObject& points = file->GetPoints(); put_sp_code(points, "spcode"); } void put_sp_code(DataObject& points, const char* code) { std::for_each(points.begin(), points.end(), std::bind2nd(std::mem_fun(&PxyPoint::PutSpCode), code)); } This does not compile (VC 7.1): c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\algorithm(21): error C2664: 'binder2nd<_Fn2>::result_type binder2nd<_Fn2>::operator ()(binder2nd<_Fn2>::argument_type & ) const': cannot convert parameter 1 from 'DataObject' to 'binder2nd<_Fn2>::argument_type & ' with [ _Fn2=mem_fun1_t<void,TPunkt,const char *> ] and [ _Fn2=mem_fun1_t<void,TPunkt,const char *> ] A reference that is not to 'const' cannot be bound to a non-lvalue c:\projects\GEOW\V12\Test\GeoTest\Model Test\ModelTest.cpp(48): see reference to function template instantiation '_Fn1 for_each<iter,binder2nd<_Fn2> >(_InIt,_InIt,_Fn1)' being compiled with [ _Fn1=binder2nd<mem_fun1_t<void,TPunkt,const char *> >, _Fn2=mem_fun1_t<void,TPunkt,const char *>, _InIt=iter ] (error message formatted with STLTask) Is this possible with our design? I would like to be able to do this without having to create a PxyPointList, that derives from DataObject and only stores PxyPoint's (my guess is that something like that would work with this code). Thanks in advance! Regards, Daniel

Daniel Lidström <daniel.lidstrom@sbg.se> writes:
Now to my problem: A PxyPoint is a sub class to DataObject, and PxyFileData::GetPoints() returns a DataObject where all the children are PxyPoint's. Now I would like to call a member function, PxyPoint::PutSpCode(const char*), on each of the children, like this:
void put_sp_code(DataObject&, const char*);
void test() { shared_ptr<PxyFileData> file(...);
DataObject& points = file->GetPoints(); put_sp_code(points, "spcode"); }
void put_sp_code(DataObject& points, const char* code) { std::for_each(points.begin(), points.end(), std::bind2nd(std::mem_fun(&PxyPoint::PutSpCode), code));
If PutSpCode is a virtual function on DataObjects, it's easy. // Using Boost.Bind because the standard binders are too tricky for // me to get right (untested); std::for_each(points.begin(), points.end(), boost::bind(&DataObject::PutSpCode, _1, code)); Otherwise I don't think you could reasonably expect anything like this to work without a cast. You'd need to create a function object with a cast in it: // using Boost.Lambda (untested) std::for_each(points.begin(), points.end(), (&boost::ll_dynamic_cast<PxyPoint&>(_1))->*(&PxyPoint::PutSpCode)(code)); or std::for_each(points.begin(), points.end(), (&boost::ll_static_cast<PxyPoint&>(_1))->*(&PxyPoint::PutSpCode)(code));
Is this possible with our design? I would like to be able to do this without having to create a PxyPointList, that derives from DataObject and only stores PxyPoint's (my guess is that something like that would work with this code).
I can't tell for sure, but this has all the markings of a design that's trying to use runtime polymorphism where it should be using compile-time polymorphism, in some form or other. BTW, what does any of this have to do with iterator_facade? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
I can't tell for sure, but this has all the markings of a design that's trying to use runtime polymorphism where it should be using compile-time polymorphism, in some form or other.
Thanks for the interesting tips! If this is possible to solve without explicitly creating a functor, that would be really cool. I'll have to study your examples carefully.
BTW, what does any of this have to do with iterator_facade?
You're right, it is totally unrelated. Sorry I referred to iterator_facade. Regards, Daniel Lidström
participants (3)
-
Daniel Lidstrom
-
Daniel Lidström
-
David Abrahams