iterator类:执行迭代器加或减时g ++中的编译器错误(在VS2010中有效)

时间:2011-07-14 03:30:58

标签: c++ iterator

我在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)操作。但无论如何,它都可以在Visual Studio 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;
}
//-------------------------------------------------------------------------------//

// -------------------------------------------- code END ---------------- //

2 个答案:

答案 0 :(得分:2)

您的迭代器operator-不会改变状态,因此它应该是常量。

答案 1 :(得分:1)

这可能不是答案,但您可以尝试以下方法:

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