[ptr_container] Const & non-const ptr_map iteration over mapped values.

Hi all!!
In my class have an internal member of type
typedef boost::ptr_map

Rodolfo Federico Gamarra skrev:
Hi all!!
In my class have an internal member of type
typedef boost::ptr_map
InternalComponentCollection; I'd like to provide const and non-const iterators, through appropriate two pairs of begin / end methods, in order to have "const Component&" and "Component&" as return type in each of the dereferencing operators. What's the way to do that?
What I tried:
Since the underlying storage relies in "pair" with a pointer, I thought of using a transform iterator to project "second" and then dereference the pointer; something like, for instance,
ComponentIterator Begin() { return boost::make_transform_iterator(fComponents.begin(), fResolver); }
where fResolver is an instance of
template
struct SecondResolver { typedef R result_type; template< template class Pair> result_type operator()(const Pair & p) const { return * p.second; } };
I would just implement this as (abbreviated) template< class R > struct X { template< class Pair > R operator()( const Pair& p ) const { return *p.second; } };
and having
typedef SecondResolver
ComponentResolver; typedef typename InternalComponentCollection::key_type KeyType; typedef typename InternalComponentCollection::mapped_type MappedType; typedef typename InternalComponentCollection::mapped_reference MappedReference; typedef typename InternalComponentCollection::iterator PairIterator; typedef boost::transform_iterator ComponentIterator; The case for const iteration is similarly implemented, using the following typedefs:
typedef SecondResolver
ConstComponentResolver; typedef const Component* /* No nested typedef for this...*/ ConstMappedType; typedef typename InternalComponentCollection::const_mapped_reference ConstMappedReference; typedef typename InternalComponentCollection::const_iterato PairConstIterator; typedef boost::transform_iterator ComponentConstIterator; My remarks about my solution are:
1) SecondResolver is not an "UnaryFunction" in the sense of the C++ standard, since there's no "argument_type" nested typedef. Tough it seems that that isn't actually required by transform_iterator. I have problems in trying to define that typedef (see 2).
Well, why do you want to define that typedef, when it is easier to infer the type automatically?
2) The actual pairs are instances of
boost::ptr_container_detail::ref_pair
so it wouldn't be right to typedef that as arg type (it's a "detail"). This class provides implicit conversion from std::pair, but no implicit conversion to std::pair. So that's why I wrote the operator() as a template function, since cannot give the operator an explicit type: nor ref_pair (being a detail), nor std::pair (not having the conversion). Should that conversion be provided?
Why? Dont map::value_type v = *m.find(x) work?
3) I wrote ConstMappedType typedef explicitly, without relying in a nested typedef in the original class. Doing
typedef const MappedType ConstMappedType;
doesn't work because the const binds to the pointer, not to the pointed type.
Again, why do you want to do this? -Thorsten
participants (2)
-
Rodolfo Federico Gamarra
-
Thorsten Ottosen