|
Boost : |
From: axter (boost_at_[hidden])
Date: 2006-01-03 19:56:16
"Thorsten Ottosen" <tottosen_at_[hidden]> wrote in message news:
<news:%3cdpeb1m$3cl$1_at_[hidden]> <dpeb1m$3cl$1_at_[hidden]>...
> > 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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk