4

When I try to compile the example code given below, I get the following error in g++ (version 4.6):

~/tmp/iterator_tmp$ g++ -ansi -Wall iteg.cpp  -o iteg
iteg.cpp:115:11: error: ‘ptrdiff_t’ does not name a type
iteg.cpp: In instantiation of ‘CMyItr<CMyBuff<double>, double>’:
/usr/include/c++/4.6/bits/stl_iterator_base_types.h:166:53:   instantiated from ‘std::iterator_traits<CMyItr<CMyBuff<double>, double> >’
/usr/include/c++/4.6/bits/stl_iterator.h:97:11:   instantiated from ‘std::reverse_iterator<CMyItr<CMyBuff<double>, double> >’
iteg.cpp:204:40:   instantiated from here
iteg.cpp:21:46: error: no type named ‘difference_type’ in ‘CMyItr<CMyBuff<double>, double>::BuffType {aka class CMyBuff<double>}’

The example compiles fine in g++ 4.4 however, as it does in Visual Studio 2010. Could somebody point what am I doing wrong here?

The two commands I used are the following in the two cases of g++ 4.6 and 4.4 respectively.

g++ -ansi -Wall iteg.cpp  -o iteg
g++-4.4 -ansi -Wall iteg.cpp  -o iteg

Thanks.

Code example:

//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
#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;

  return 0;
}
//---------------------------------------------------------------------------//
user193272
  • 984
  • 1
  • 12
  • 18
  • James McNellis posted (he deleted that post, it seems) that adding "std::" to ptrdiff_t would work. He was correct. Using `typedef std::ptrdiff_t difference_type;` fixed the error. Thanks, James. Also, Sjoerd's suggestion of including stddef.h also works. – user193272 Jul 17 '11 at 22:34

1 Answers1

6

ptrdiff_t is defined in <stddef.h>. Add #include <stddef.h> to the top of your code and you'll be fine.

In C++, system headers are allowed, but not required, to include other system headers.

Update: #include <cstddef> will work as well, but then you'll have to use std::ptrdiff_t.

Sjoerd
  • 6,837
  • 31
  • 44
  • Just using `std::ptrdiff_t` works. And, just including `stddef.h` also works. As does including `cstddef`. Thanks. – user193272 Jul 17 '11 at 22:36
  • Q. Why don't I face the same problem in g++ 4.4 (or in Visual Studio 2010)? – user193272 Jul 17 '11 at 22:38
  • 4
    @user193272: The GNU project has some bugs in its implementations of the C standard headers and in #including things they don't really need. They have been cleaning those bugs up over time. Code that compiles in 4.2 might not compile in 4.4, code that compiles in 4.4 might not compile in 4.6. Bottom line: Your code is using ptrdiff_t, so your code should #include the file that defines it. Don't depend on others to do it for you because one day it won't work. – David Hammen Jul 17 '11 at 23:09
  • Re Sjoerd's answer: It is better to #include and use std::ptrdiff_t rather than #including and using ptrdiff_t. The former is what the standard recommends. The latter is explicitly marked as deprecated in the standard. – David Hammen Jul 17 '11 at 23:11
  • @David Opinions differ on that point. See http://stackoverflow.com/questions/5079325/should-i-include-stddef-h-or-cstddef and http://stackoverflow.com/questions/2587445/are-c-functions-declared-in-c-headers-guaranteed-to-be-in-the-global-namesp/2588103#2588103 – Sjoerd Jul 18 '11 at 20:23