$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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.