How do I loop over consecutive pairs in an STL container using range-based loop syntax?

后端 未结 4 530
深忆病人
深忆病人 2020-12-10 09:21

How do I create a custom class to loop over consecutive pairs of items in a STL container using a range-based loop?

This is the syntax and output I want:

<         


        
4条回答
  •  感动是毒
    2020-12-10 10:05

    Okay, an hour with no answers, I've come up with a solution which works. Note that this uses my own FixedLengthVector which is exactly what it sounds like.

    template 
    class Grouped {
    private:
      // length of grouped objects
      static const unsigned length_ = 2;
      // hold pointer to base container to avoid comparing incompatible iterators
      T * base_container_;
    public:
      // constructor
      Grouped(T & base_container) :
          base_container_(&base_container) {
      }
      // iterator
      class iterator {
      private:
        // hold pointer to base container to avoid comparing incompatible iterators
        T * base_container_;
        // hold pointers to objects in base container
        FixedLengthVector ptr_;
        // hold iterator to last object
        typename T::iterator last_iterator_;
      public:
        // constructor
        iterator(T & base_container, typename T::iterator & it)
            : base_container_(&base_container),
              last_iterator_(it) {
          // set up pointers if possible
          unsigned i = 0;
          // check for end iterator
          if (last_iterator_ == base_container_->end()) {
            ptr_.fill(NULL);
            return;
          }
          // set up first object
          ptr_[0] = &*last_iterator_;
          // set up next objects
          for (unsigned i = 1; i < length_; ++i) {
            ++last_iterator_;
            if (last_iterator_ == base_container_->end()) {
              ptr_.fill(NULL);
              return;
            }
            ptr_[i] = &*last_iterator_;
          }
        }
        // dereference operator
        FixedLengthVector & operator * (void) {
          assert(ptr_[0] != NULL);
          return ptr_;
        }
        // pre-increment
        iterator & operator ++ (void) {
          // can't increase past end
          assert(last_iterator_ != base_container_->end());
          // find next iterator
          ++last_iterator_;
          if (last_iterator_ == base_container_->end()) {
            ptr_.fill(NULL);
            return * this;
          }
          // cycle pointers left
          for (unsigned i = 1; i < length_; ++i) {
            ptr_[i - 1] = ptr_[i];
          }
          ptr_[length_ - 1] = &*last_iterator_;
          return * this;
        }
        // equality comparison
        bool operator == (const iterator & that) const {
          return base_container_ == that.base_container_ &&
                 last_iterator_ == that.last_iterator_;
        }
        // inequality comparison
        bool operator != (const iterator & that) const {
          return !(*this == that);
        }
      };
      // end iterator
      iterator end() {
        return iterator(*base_container_, base_container_->end());
      }
      // begin iterator
      iterator begin() {
        return iterator(*base_container_, base_container_->begin());
      }
    };
    

提交回复
热议问题