Boost logo

Boost Users :

From: johny5.coder_at_[hidden]
Date: 2008-05-06 09:36:10


Hello to everybody.

Im using the great library Boost.Foreach and very happy with it,
however currently I met some strange issue I want to show you.

Im using custom wrappers to iterate over mapped values in std::map<>
container. Here is the wrapper:

template<typename CONT>
struct Select2ndIt
{
        CONT& cont;

        Select2ndIt(CONT& cont) : cont(cont) {}

        typedef typename CONT::mapped_type value_type;

        struct iterator : public std::iterator
                <typename CONT::iterator::iterator_category, value_type, typename
CONT::iterator::distance_type>
        {
                typename CONT::iterator it;

// typedef typename CONT::iterator::difference_type difference_type;
                typedef value_type* pointer;
                typedef value_type& reference;

                iterator(typename CONT::iterator it) : it(it) {}

                bool operator==(const iterator& other) const { return it == other.it; }
                bool operator!=(const iterator& other) const { return it != other.it; }
                iterator& operator++() { ++it; return *this; }
                iterator& operator++(int) { it++; return *this; }
                iterator& operator--() { --it; return *this; }
                iterator& operator--(int) { it--; return *this; }
                reference operator*() const { return it->second; }
                pointer operator->() const { return &it->second; }
        };

        struct const_iterator : public std::iterator
                <typename CONT::const_iterator::iterator_category, value_type,
typename CONT::const_iterator::distance_type>
        {
                typename CONT::const_iterator it;

// typedef typename CONT::const_iterator::difference_type difference_type;
                typedef const value_type* pointer;
                typedef const value_type& reference;

                const_iterator(typename CONT::const_iterator it) : it(it) {}

                bool operator==(const const_iterator& other) const { return it == other.it; }
                bool operator!=(const const_iterator& other) const { return it != other.it; }
                const_iterator& operator++() { ++it; return *this; }
                const_iterator& operator++(int) { it++; return *this; }
                const_iterator& operator--() { --it; return *this; }
                const_iterator& operator--(int) { it--; return *this; }
                reference operator*() const { return it->second; }
                pointer operator->() const { return &it->second; }
        };

        iterator begin()
        {
                return iterator(cont.begin());
        }
        iterator end()
        {
                return iterator(cont.end());
        }
        const_iterator begin() const
        {
                return const_iterator(cont.begin());
        }
        const_iterator end() const
        {
                return const_iterator(cont.end());
        }
};

template<typename CONT>
Select2ndIt<CONT> select2nd(CONT& cont) { return Select2ndIt<CONT>(cont); }

And usage:

        std::map<int, unsigned> cont;
        BOOST_FOREACH(unsigned& value, alg::select2nd(cont))
                value = 0;

And MSVS 8.0 tells: error C2440: 'initializing' : cannot convert from
'const unsigned int' to 'unsigned int &'

Without wrappers I can easily iterate as a non-const value:

        std::map<int, unsigned> cont;
        typedef std::pair<const int, unsigned> value_type;
        BOOST_FOREACH(value_type& value, cont)
                value.second = 0;

works great.

I guess my wrappers very close to STL iterators (they even inherit
from std::iterator), however some unwanted constness is appearing, so
I afraid it is some issue with Boost.Foreach library.

I hope for some help or advice about this problem.

Thanks. Evgeny.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net