Boost logo

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