How to implement an STL-style iterator and avoid common pitfalls?

后端 未结 8 788
刺人心
刺人心 2020-11-22 16:45

I made a collection for which I want to provide an STL-style, random-access iterator. I was searching around for an example implementation of an iterator but I didn\'t find

相关标签:
8条回答
  • 2020-11-22 17:34

    First of all you can look here for a list of the various operations the individual iterator types need to support.

    Next, when you have made your iterator class you need to either specialize std::iterator_traits for it and provide some necessary typedefs (like iterator_category or value_type) or alternatively derive it from std::iterator, which defines the needed typedefs for you and can therefore be used with the default std::iterator_traits.

    disclaimer: I know some people don't like cplusplus.com that much, but they provide some really useful information on this.

    0 讨论(0)
  • 2020-11-22 17:34

    And now a keys iterator for range-based for loop.

    template<typename C>
    class keys_it
    {
        typename C::const_iterator it_;
    public:
        using key_type        = typename C::key_type;
        using pointer         = typename C::key_type*;
        using difference_type = std::ptrdiff_t;
    
        keys_it(const typename C::const_iterator & it) : it_(it) {}
    
        keys_it         operator++(int               ) /* postfix */ { return it_++         ; }
        keys_it&        operator++(                  ) /*  prefix */ { ++it_; return *this  ; }
        const key_type& operator* (                  ) const         { return it_->first    ; }
        const key_type& operator->(                  ) const         { return it_->first    ; }
        keys_it         operator+ (difference_type v ) const         { return it_ + v       ; }
        bool            operator==(const keys_it& rhs) const         { return it_ == rhs.it_; }
        bool            operator!=(const keys_it& rhs) const         { return it_ != rhs.it_; }
    };
    
    template<typename C>
    class keys_impl
    {
        const C & c;
    public:
        keys_impl(const C & container) : c(container) {}
        const keys_it<C> begin() const { return keys_it<C>(std::begin(c)); }
        const keys_it<C> end  () const { return keys_it<C>(std::end  (c)); }
    };
    
    template<typename C>
    keys_impl<C> keys(const C & container) { return keys_impl<C>(container); }
    

    Usage:

    std::map<std::string,int> my_map;
    // fill my_map
    for (const std::string & k : keys(my_map))
    {
        // do things
    }
    

    That's what i was looking for. But nobody had it, it seems.

    You get my OCD code alignment as a bonus.

    As an exercise, write your own for values(my_map)

    0 讨论(0)
提交回复
热议问题