Re: [boost] ptr_container: ptr_map_adapter interface

"Thorsten Ottosen" <tottosen@dezide.com> wrote in message news: <news:%3cdpeb1m$3cl$1@sea.gmane.org> <dpeb1m$3cl$1@sea.gmane.org>...
4. ptr_vector produces a runtime error when assigning one container to
another via operator[]
I need to see an as small as possible test that shows this. Given that
you prohibit slicing (by declaring an explicit copy constructor or by
removing copyability totally) it might be due to this.
I posted a link with all the test code, which is split up with comments: See following link: http://code.axter.com/BoostPtrContainerTestCode.zip All the classes have copy constructors. Here's the section of code which I pulled from above link: #ifdef INCLUDE_CODE_THAT_WILL_CAUSE_RUNTIME_FAILURE_ //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// //boost::ptr_vector fails assignment test because, //the following code will produce a runtime failure for(i = 0;i < ContainerOfOriginalShapes.size();++i) CopyViaContainerForLoopOp[i] = ContainerOfOriginalShapes[i]; //-------------------------------------------------------------------------- --------------------------------------------------- //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// #endif //INCLUDE_CODE_THAT_WILL_CAUSE_RUNTIME_FAILURE_ I believe the runtime error occurs on the destructor of the containers after performing the above logic.
5. Produces multiple compiler warnings when using VC++ 7.1
Yes. Vc7.1 and other compilers warn against far too much. ADL for
example.
6. Will fail to clone the right type if a derived-derived type fails to
implement the clone method.
There is no magic like in shared_ptr here. That would impose some
overhead.
Shared_ptr would not clone the type, and instead share the object, which is what you're trying to avoid with a container of pointers.
7. Does not have the standard vector::assign member function that takes
(size_type, const Type&)
Might be possible to add, though the second argument might be an
auto_ptr, a bald pointer or a reference.
I'm considering adding a little more initialization help
in boost.assign:
http://www.boost.org/libs/assign/doc/index.html#ptr_push_back
2. Can not insert using an abstract pointer.
implement new_clone().
Can you provide an example? I don't see any examples for using these containers with an abstract pointer in the boost links.
3. Can not find using an abstract pointer.
please produce a minimal example after implmenting new_clone().
Again, need example usage.
4. Crashes when inserting via de-referenced iterator from another
container
ditto.
See previously posted link.
5. boost::ptr_set is publicly derived from boost::ptr_set_adapter,
however ptr_set_adapter does not have a virtual function, nor does
any of it's base classes.
The classes are not copyable, so you won't run into slicing problems.
The inheritance is purely for inheriting implementation.
I see. I will remove this item from my list.
6. Fails to compile when used with ptr_set::const_reverse_iterator
logic
please produce a minimal example.
Here's the section of code which I pulled from above link: typedef boost::ptr_map<int, BaseNotAbstract> ContainerTypeBaseNotAbstract; #ifdef INCLUDE_CODE_THAT_DOES_NOT_COMPILE_ //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// //Instead of using first and second iterator members, boost::ptr_map uses operator-> and key() functions to access first and second. However, it still fails to compile when using const_reverse_iterator, so //the following lines of code will not compile: for(ContainerTypeBaseNotAbstract::const_reverse_iterator r_c_iter = mIntToBase.rbegin();r_c_iter != mIntToBase.rend();++r_c_iter) { r_c_iter->GetData(); } //-------------------------------------------------------------------------- --------------------------------------------------- //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// #endif //INCLUDE_CODE_THAT_DOES_NOT_COMPILE_ typedef boost::ptr_set<Shape> ContainerTypeIntToShape; #ifdef INCLUDE_CODE_THAT_DOES_NOT_COMPILE_ //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// //Fails to compile when used with ptr_set::const_reverse_iterator logic for (ContainerTypeIntToShape::const_reverse_iterator i = setShape.rbegin();i != setShape.rend();++i) i->draw(); //-------------------------------------------------------------------------- --------------------------------------------------- //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// #endif //INCLUDE_CODE_THAT_DOES_NOT_COMPILE_ You should be able to duplicate this compile error very easily.
boost::ptr_map
1. Unable to compile with an abstract type
implement new_clone();
Again, need example usage.
2. Does not have an insert type for std::pair
and cannot provide one without allowing memory leaks.
3. Can not insert using a constant for 1st argument
ditto.
5. Does not support the pointer as the key type
right. use shared_ptr or something then.
Shared_ptr does not give you cloning logic. Using the cow_ptr or the copy_ptr, you do get cloning logic, and you do get support for the pointer as the key type.
6. Fails to compile insert to iterator type
please produce minimal example.
Here's the section of code which I pulled from the posted link: #ifdef INCLUDE_CODE_THAT_DOES_NOT_COMPILE_ //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// //boost::ptr_map::insert fails to compile with an iterator or const_iterator, the following //line of code will not compile: ContainerTypeBaseNotAbstract mIntToBase2; for (ContainerTypeBaseNotAbstract::const_iterator i = mIntToBase.begin();i != mIntToBase.end();++i) mIntToBase2.insert(i); for (ContainerTypeBaseNotAbstract::iterator i = mIntToBase.begin();i != mIntToBase.end();++i) mIntToBase2.insert(i); //-------------------------------------------------------------------------- --------------------------------------------------- //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// #endif //INCLUDE_CODE_THAT_DOES_NOT_COMPILE_ Again, you should be able to duplicate this compile error very easily.
7. ptr_map::equal_range does not return std::pair<iterator, iterator>
type as does the standard map::equal_range
nor does it need to. the two classes are used in vastly different
domains and so generic code working with them both is an illusion.
I still see this as a detraction from using the ptr_map container, since it requires knowledge of a different interface. It's easier for a developer to pickup on a class that uses the same interface as an existing well known class. A developer can learn how to use std::map<int, cow_ptr<T> > much faster then using boost::ptr_map, because they don't have to learn a new container interface.
8. Does not use the standard first and second iterator members as does
the standard map::iterator
right, you're not allowed access to the pointer.
9. Instead of using first and second iterator members, boost::ptr_map
uses operator-> and key() functions to access first and second.
However, it still fails to compile when using
const_reverse_iterator.
A minimal example is appreciated.
Here's the section of code which I pulled from the posted link: #ifdef INCLUDE_CODE_THAT_DOES_NOT_COMPILE_ //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// //Instead of using first and second iterator members, boost::ptr_map uses operator-> and key() functions to access first and second. However, it still fails to compile when using const_reverse_iterator, so //the following lines of code will not compile: for(ContainerTypeBaseNotAbstract::const_reverse_iterator r_c_iter = mIntToBase.rbegin();r_c_iter != mIntToBase.rend();++r_c_iter) { r_c_iter->GetData(); } //-------------------------------------------------------------------------- --------------------------------------------------- //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// #endif //INCLUDE_CODE_THAT_DOES_NOT_COMPILE_ Could you please provide some example usage code for ptr_set and ptr_map with an abstract pointer type. I highly recommend adding example code on the boost link.
participants (1)
-
axter