简体   繁体   English

包装迭代句柄,用于基于范围的for循环

[英]Wrap iteration handle for use in range-based for-loops

I use an API that comes with an iteration functionality using a void* handle. 我使用带有使用void*句柄的迭代功能的API。

void* handle = BrowseInit();
while (BrowseGetNext(handle))
{
  // ...
  int x = BrowseGetData(handle);
}
BrowseFree(handle);

How would I go about wrapping this into a C++11 iterator for use in range-based for-loops? 我将如何将其包装到C ++ 11迭代器中以用于基于范围的for循环? Since the value of the handle doesn't actually change, I need some trickery in operator != () . 由于handle的值实际上没有改变,我在operator != ()需要一些技巧。

class Iterator
{
public:

  friend class it;
  class it
  {
  public:

    it(Iterator* data) : _data(data) { }
    bool operator != (const it& other) const
    {
      // what should I put in here?
    }
    const it& operator ++ ()
    {
      BrowseGetNext(_data->_handle);
    }
    int operator * () const
    {
      return BrowseGetData(_data->_handle);
    }

  private:
    Iterator* _data;
  };

  Iterator() : _handle(BrowseInit()) { }
  ~Iterator() 
  {
    BrowseFree(_handle);
  }

  it begin() const
  {
    return it(this);
  }
  it end() const
  {
    return it(nullptr);
  }

private:

  void* _handle;
};

This should work. 这应该工作。

class Iterator
{
   public:

      friend class it;
      class it
      {
         public:

            // Constructor for begin().
            it(Iterator* data) : _data(data), index_(0) { }

            // Constructor for end().
            it(Iterator* data, int) : _data(data), index_(-1) { }

            bool operator != (const it& other) const
            {
               return !(*this == other);
            }
            bool operator == (const it& other) const
            {
               return ( this->_data == other._data && this->_index == rhs._index );
            }

            const it& operator ++ ()
            {
               // Increment the index if there's more data.
               // Otherwise, set it to -1.
               if ( BrowseGetNext(_data->_handle) )
               {
                  ++index_;
               }
               else
               {
                  index_ = -1;
               }
            }

            int operator * () const
            {
               return BrowseGetData(_data->_handle);
            }

         private:
            Iterator* _data;
            int _index;
      };

      Iterator() : _handle(BrowseInit()) { }
      ~Iterator() 
      {
         BrowseFree(_handle);
      }

      it begin() const
      {
         return it(this);
      }
      it end() const
      {
         return it(this, 0);
      }

   private:

      void* _handle;
};

Update: Setup iterator_traits for it 更新:为it设置iterator_traits

template <> std::iterator_traits<Iterator::it>
{
    typedef int difference_type;
    typedef int value_type;
    typedef int* pointer;
    typedef int& reference;
    typedef std::forward_iterator_tag iterator_category;
};

Thanks for the suggestion, Yakk. 谢谢你的建议,Yakk。

Update 2 更新2

Instead of specializing std::iterator for Iterator::it , derive Iterator::it from std::iterator . 而不是为Iterator::it专门化std::iteratorIterator::itstd::iterator派生Iterator::it

class it : public std::iterator<std::forward_iterator_tag, int, int>
{
....
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM