g++ 4.6 complains about iterator difference type. g++ 4.4 and Visual Studio don't
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开发者_如何学Go_;
};
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;
}
//---------------------------------------------------------------------------//
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
.
精彩评论