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

时间:2014-07-22 16:36:30

标签: c++ c++11 ranged-loops

我使用带有void*句柄的迭代功能的API。

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

我如何将其包装到C ++ 11迭代器中以用于基于范围的for循环?由于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;
};

1 个答案:

答案 0 :(得分:1)

这应该有用。

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;
};

更新:iterator_traits

的设置it
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;
};

感谢你的建议,Yakk。

更新2

不是为std::iterator专门化Iterator::it,而是从Iterator::it派生std::iterator

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