|
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