How to remove constness of const_iterator?

后端 未结 9 2505
囚心锁ツ
囚心锁ツ 2020-11-27 03:21

As an extension to this question Are const_iterators faster?, I have another question on const_iterators. How to remove constness of a const_iterator

9条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-27 04:12

    In the answers to your previous post, there were a couple of people, me included, that recommended using const_iterators instead for non-performance related reasons. Readability, traceability from the design board to the code... Using const_iterators to provide mutating access to a non-const element is much worse than never using const_iterators at all. You are converting your code into something that only you will understand, with a worse design and a real maintainability pain. Using const just to cast it away is much worse than not using const at all.

    If you are sure you want it, the good/bad part of C++ is that you can always get enough rope to hang yourself. If your intention is using const_iterator for performance issues, you should really rethink it, but if you still want to shoot your foot off... well C++ can provide your weapon of choice.

    First, the simplest: if your operations take the arguments as const (even if internally apply const_cast) I believe it should work directly in most implementations (even if it is probably undefined behavior).

    If you cannot change the functors, then you could tackle the problem from either side: provide a non-const iterator wrapper around the const iterators, or else provide a const functor wrapper around the non-const functors.

    Iterator façade, the long road:

    template 
    struct remove_const
    {
        typedef T type;
    };
    template 
    struct remove_const
    {
        typedef T type;
    };
    
    template 
    class unconst_iterator_type
    {
        public:
            typedef std::forward_iterator_tag iterator_category;
            typedef typename remove_const<
                    typename std::iterator_traits::value_type
                >::type value_type;
            typedef value_type* pointer;
            typedef value_type& reference;
    
            unconst_iterator_type( T it )
                : it_( it ) {} // allow implicit conversions
            unconst_iterator_type& operator++() {
                ++it_;
                return *this;
            }
            value_type& operator*() {
                return const_cast( *it_ );
            }
            pointer operator->() {
                return const_cast( &(*it_) );
            }
            friend bool operator==( unconst_iterator_type const & lhs,
                    unconst_iterator_type const & rhs )
            {
                return lhs.it_ == rhs.it_;
            }
            friend bool operator!=( unconst_iterator_type const & lhs,
                    unconst_iterator_type const & rhs )
            {
                return !( lhs == rhs );
            }
        private:
            T it_;  // internal (const) iterator
    };
    

提交回复
热议问题