Boost logo

Boost :

From: Eelis van der Weegen (eelis_at_[hidden])
Date: 2004-12-10 16:32:26


Two issues:

(1.) I stumbled upon a strange inconsistency in boost::ptr_map's
iterator interface. I've attached some demonstration code that shows the
problem.

(2.) Given a (nonempty) const std::map<X, Y*> object, it is possible to
retrieve a Y& from it. Given a const boost::ptr_map<X, Y> object, it is
not possible (without casting) to retrieve a Y& from it.
Thus, it is not possible (in general) to refactor code which uses a
std::map<X, Y*> combined with manual ptr_map-like lifetime/ownership
management to use a boost::ptr_map<X, Y> without changing const semantics.

Was this effect intentional? If so, why was this approach chosen?
It seems like ptr_map attempts to "hide" the level of indirection that a
standard container of pointers has. While this may be desirable, I think
it should be mentioned in the documentation since it can come as a
surprise to people (like me) who actually try to perform the refactoring
mentioned above.

Eelis


#include <map>
#include <boost/smart_container/ptr_map.hpp>

typedef std::map<int, int *> M;
typedef boost::ptr_map<int, int> N;

void f (M & m)
{
  M::iterator i = m.begin();
  M::iterator const ci = i;

  int & a = *(i->second); // ok
  int & b = *(ci->second); // ok
}

void g (N & n)
{
  N::iterator i = n.begin();
  N::iterator const ci = i;

  int & a = *i; // ok
  int & b = *ci; // error: invalid initialization of reference of type 'int&' from expression of type 'const int'
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk