【问题标题】:Wrap iteration handle for use in range-based for-loops包装迭代句柄以用于基于范围的 for 循环
【发布时间】:2014-09-13 14:31:38
【问题描述】:

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

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

【问题讨论】:

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


【解决方案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;
};

更新:为 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;
};

谢谢你的建议,Yakk。

更新 2

不要将std::iterator 专门用于Iterator::it,而是从std::iterator 派生Iterator::it

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-20
  • 2011-10-20
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
相关资源
最近更新 更多