what is the preferred way to expose custom STL-style iteration?

前端 未结 4 1916
春和景丽
春和景丽 2020-12-19 04:47

(also see Is there a good way not to hand-write all twelve required Container functions for a custom type in C++? )


For a class such as

namespa         


        
4条回答
  •  猫巷女王i
    2020-12-19 05:19

    In order to create a valid iterator, you must ensure that std::iterator_traits is valid. This means you must set the iterator category among other things.

    An iterator should implement iterator(), iterator(iterator&&), iterator(iterator const&), operator==, operator !=, operator++, operator++(int), operator*, operator=, and operator->. It's also a good idea to add operator< and operator+ if you can (you can't always, e.g. linked lists.)

    template 
    class foo
    {
    public:
    
      using value_type = T;
      class iterator 
      { 
      public:
        using value_type = foo::value_type;
        using iterator_category = std::random_access_iterator_tag;
        // or whatever type of iterator you have...
        using pointer = value_type*;
        using reference = value_type&;
        using difference_type = std::ptrdiff_t;
    
        // ... 
      };
    
      class const_iterator 
      {
        // ... 
      };
    
      iterator begin() { /*...*/ }
      iterator end() { /*...*/ }
    
      const_iterator cbegin() const { /*...*/ }
      const_iterator cend() const { /*...*/ }
    
      /* ... */
    };
    

    See: http://en.cppreference.com/w/cpp/iterator/iterator_traits for more information on what you need to make a valid iterator. (Note: You also need certain properties to be a valid "container", like .size())

    Ideally you should use member functions for begin and end, but it's not required... you can also overload std::begin and std::end. If you don't know how to do that, I suggest you use member functions.

    You should create begin() const and end() const, but it should be an alias for cbegin(), NEVER the same as begin()!

提交回复
热议问题