迭代器类:在g++中进行迭代器加法或减法时编译器错误(适用于VS2010)

iterator class: compiler error in g++ while doing iterator add or subtract (works in VS2010)

本文关键字:迭代器 错误 编译器 适用于 VS2010 g++      更新时间:2023-10-16

我正在用c++实现一个数组(出于各种原因,其中之一是了解自定义迭代器)。

在测试时,我注意到它不能在g++ 4.4中编译,但在Visual Studio 2010中运行良好。

我在下面包含了一个示例程序。在这里,我输出了一个玩具数组的最后一个值,这个玩具数组是我使用模板和附带的迭代器类实现的。我得到的编译器错误如下:

$ g++-4.4 -ansi -Wall  -std=c++0x mybuffer.cpp -o mybuffer
In file included from /usr/include/c++/4.4/bits/stl_algobase.h:69,
                 from /usr/include/c++/4.4/memory:49,
                 from mybuffer.cpp:1:
/usr/include/c++/4.4/bits/stl_iterator.h: In member function ‘std::reverse_iterator<_Iterator> std::reverse_iterator<_Iterator>::operator+(typename std::iterator_traits<_Iter>::difference_type) const [with _Iterator = CMyItr<CMyBuff<double>, double>]’:
mybuffer.cpp:205:   instantiated from here
/usr/include/c++/4.4/bits/stl_iterator.h:221: error: passing ‘const CMyItr<CMyBuff<double>, double>’ as ‘this’ argument of ‘CMyItr<T, typename T::value_type> CMyItr<T, elem_type>::operator-(typename T::difference_type) [with T = CMyBuff<double>, elem_type = double]’ discards qualifiers

如果我做*(RItr+1)操作,错误发生,而不是如果我做*(++ RItr)操作。在visualstudio 2010中,无论哪种情况,它都可以工作。

在g++ 2.95中也得到相同的编译错误。没有在Visual Studio 6中尝试过。

有人能解释一下我做错了什么以及如何解决它吗?

谢谢。PS:使用g++ 4.6完全是另一个问题,但那是以后的事了。

//-------------------------------------------- example code ----------------//
//------------------------------------------------------------------------------//
//------------------------------------------------------------------------------//
#include <memory> 
#include <iostream>
#include <iterator>
template < typename T, typename elem_type=typename T::value_type> 
               class CMyItr {
public:
  typedef T BuffType;
  typedef CMyItr<T> self_type;
  typedef CMyItr<self_type, elem_type> iterator;
  typedef typename std::bidirectional_iterator_tag iterator_category;
  typedef typename BuffType::value_type value_type;
  typedef typename BuffType::size_type size_type;
  typedef typename BuffType::pointer pointer;
  typedef typename BuffType::const_pointer const_pointer;
  typedef typename BuffType::reference reference;
  typedef typename BuffType::const_reference const_reference;
  typedef typename BuffType::difference_type difference_type;

  CMyItr( BuffType *pB, size_type pos):
    PtrItr_(pB), PtrPos_(pos){
  };

  friend class CMyItr< const T, const elem_type>;
  elem_type &operator*(){
    return (*PtrItr_)[PtrPos_];
  };
  elem_type *operator->(){
    return &(operator*());
  };
  self_type & operator++(){
    ++PtrPos_;
    return *this;
  };
  self_type operator++(int){
    self_type tmp(*this);
    ++(*this);
    return tmp;
  };
  self_type operator+(difference_type n) {
    self_type tmp(*this);
    tmp.PtrPos_ = tmp.PtrPos_ + n;
    return tmp;
  };
  self_type &operator+=(difference_type n){
    PtrPos_ = PtrPos_ + n;
    return *this;
  };

  self_type & operator--(){
    --PtrPos_;
    return *this;
  };
  /*!
    The decrement operator which decrements the position index.
  */
  self_type operator--(int){
    self_type tmp(*this);
    --(*this);
    return tmp;
  };
  self_type operator-(difference_type n) {
    self_type tmp(*this);
    tmp.PtrPos_ =  tmp.PtrPos_ - n;
    return tmp;
  };
  self_type &operator-=(difference_type n){
    PtrPos_ -= n;
    return *this;
  };
  bool operator!=(const self_type &other) const {
    return PtrPos_ != other.PtrPos_ && PtrItr_ == other.PtrItr_;
  };
  bool operator==(const self_type &other) const {
    return PtrPos_ == other.PtrPos_ && PtrItr_ == other.PtrItr_;
  };
private:
  BuffType * PtrItr_;
  size_type PtrPos_;
};

//----------------------------------------------------------------------//
//----------------------------------------------------------------------//
template < typename T > class CMyBuff {
public:
  enum {default_size = 4 };
  typedef CMyBuff<T> self_type;
  typedef T value_type;
  typedef T & reference;
  typedef const T & const_reference;
  typedef T * pointer;
  typedef const T * const_pointer;
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;
  typedef CMyItr<self_type> iterator;
  typedef CMyItr<const self_type> const_iterator;
  typedef std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const iterator> const_reverse_iterator;
  /*! Starting for forward iterator.*/
  iterator begin(){
    return iterator(this, 0);
  };
  /*! Forward iterator should go till here.*/
  iterator end(){
    return iterator(this, Size_);
  };
  /*! Starting for constant forward iterator.*/
  const_iterator begin() const {
    return const_iterator(this, 0);
  };
  /*! Constant forward iterator should go till here.*/
  const_iterator end() const {
    return const_iterator(this, Size_);
  };
  /*! Reverse iterator starts from here.*/
  reverse_iterator rbegin(){
    return reverse_iterator(end());
  }
  /*! Reverse iterator end.*/
  reverse_iterator rend() {
    return reverse_iterator(begin());
  }
  /*! Constant reverse iterator starting point.*/
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(end());
  }
  /*! Constant reverse iterator should end here.*/
  const_reverse_iterator rend() const {
    return const_reverse_iterator( begin());
  }
  /* Ctor for my buffer*/
  explicit CMyBuff(size_type capacity = default_size): 
    Ptr_(NULL),
    Size_(capacity) {
    Ptr_ = new value_type [sizeof(value_type) * Size_];
    Ptr_[0] = 0;
    Ptr_[1] = 1;
    Ptr_[2] = 8;
    Ptr_[3] = 27;
  };

  ~CMyBuff() {
    delete [] Ptr_;
  }

  reference operator[](size_type i){
    return rAtUnChecked(i);
  };
  const_reference operator[](size_type i) const {
    return rAtUnChecked(i);
  };
  size_type size() const {
    return Size_;
  };

  reference rAtUnChecked(size_type k) const {
    return Ptr_[k];
  };
private:
  pointer Ptr_;
  size_type Size_;
};

//------------------------------------------------------------------//
//-----------------------------------------  MAIN ------------------//
// Use the following command line to compile:
// g++-4.4 -ansi -Wall  -std=c++0x mybuffer.cpp -o mybuffer
int main(){
  CMyBuff<double> Buffer;
  CMyBuff < double >::reverse_iterator RItr = Buffer.rbegin();
  //prints last but one element
  std::cout << *(++RItr) << std::endl;
  // The following doesn't compile on g++. Get const related error 
  // containing "discards qualifier"
  //std::cout << *(RItr + 1) << std::endl;
  return 0;
}
//-------------------------------------------------------------------------------//

//-------------------------------------------- 代码结束 ----------------//

你的迭代器的operator-不会改变状态,所以它应该是const。

这可能不是一个答案,但你可以试着这样做:

  1. change, difference_type n to const difference_type &n
  2. operator +()operator -()声明为const(因为它们不影响this)看看是否有帮助。