std :: set of boost :: weak_ptr <T>- Как получить const_iterator для const T? - PullRequest
2 голосов
/ 26 марта 2011

У меня есть класс, содержащий std::set из boost::weak_ptr<T>.У меня есть две функции begin () и end (), которые возвращают итератор в контейнер.Однако я не хочу, чтобы клиенты могли изменять T.Простой возврат const_iterator не сработает, потому что T, на который указывает boost::weak_ptr, будет редактируемым.

Я хочу вернуть const_iterator в std::set<boost::weak_ptr<T const> >.Кастинг от std::set<boost::weak_ptr<T> >::const_iterator не работает.Есть ли способ получить поведение, которое я хочу?

1 Ответ

5 голосов
/ 26 марта 2011

Вы можете написать итератор преобразования для преобразования weak_ptr<T> в weak_ptr<const T>. Поскольку вы уже используете Boost, вы можете использовать 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;
};

Если вы не хотите использовать boost::transform_iterator, написать свою собственную задачу довольно просто. Я показал, как это сделать, в ответе на другой вопрос .

...