I have class containing an std::set
of boost::weak_ptr<T>
. I have two functions begin() and end() that return an iterator to the container. However, I don't want clients to be able to modify T
. Simply returning a const_iterator
won't work, because the T
pointed to by the boost::weak_ptr
will be editable.
What I want to do is return a const_iterator
to std::set<boost::weak_ptr<T const> >
. Casting from std::set<boost::weak_ptr<T> >::const_iterator
does not work. Is there any way to get the behaviour I want?
You can write a transform iterator to convert the weak_ptr<T>
to a weak_ptr<const T>
. Since you're already using Boost, you can use boost::transform_iterator
:
#include <boost/iterator/transform_iterator.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <set>
// Functor to transform a weak_ptr<T> to a weak_ptr<const T>
template <typename T>
struct make_weak_ptr_const
: std::unary_function<boost::weak_ptr<T>, boost::weak_ptr<const T> >
{
boost::weak_ptr<const T> operator()(const boost::weak_ptr<T>& p) const
{
return p;
}
};
struct S { };
// Container demonstrating use of make_weak_ptr_const:
struct my_awesome_container
{
typedef std::set<boost::weak_ptr<S> > BaseSet;
typedef BaseSet::const_iterator BaseIterator;
typedef boost::transform_iterator<
make_weak_ptr_const<S>,
BaseIterator
> iterator;
iterator begin() const
{
return TransformedIterator(data.begin());
}
iterator end() const
{
return TransformedIterator(data.end());
}
std::set<boost::weak_ptr<S> > data;
};
If you don't want to use boost::transform_iterator
, it is a straightforward task to write your own. I showed how to do this in an answer to another question.