Template declaration issue with the scope
Hi,
I have a code which gets compiled using gcc 2.3. However I am getting some errors with gcc 3.4.6.
Here is the code snippet:
Code:
NAMESPACE_BEGIN(utils)
//
// template class list
//
template <class _Ty>
class list
{
protected:
//
// struct Node & Nodeptr
// - Each element in the list is a struct Node
//
struct Node;
friend struct Node;
typedef Node *Nodeptr;
public:
//
// This is what is being defined (the type of 'this')
//
typedef list<_Ty> _Myt;
//
// Forward & friend declarations for the iterators
//
class iterator;
friend class iterator;
class const_iterator;
friend class const_iterator;
//
// iterator()
//
class iterator
{
public:
// Constructors
iterator()
{
}
iterator(Nodeptr __P)
: _Ptr(__P)
{
}
_Ty &operator *() const
{
return Acc::Value(_Ptr);
}
// Prefix ++
iterator& operator ++()
{
_Ptr = Acc::Next(_Ptr);
return (*this);
}
// Postfix ++
iterator operator ++(int)
{
iterator _Tmp = *this;
++*this;
return (_Tmp);
}
// Prefix --
iterator& operator --()
{
_Ptr = Acc::Prev(_Ptr);
return (*this);
}
// Postfix --
iterator operator --(int)
{
iterator _Tmp = *this;
--*this;
return (_Tmp);
}
bool operator ==(const iterator& __X) const
{
return (_Ptr == __X._Ptr);
}
bool operator !=(const iterator& __X) const
{
return (!(*this == __X));
}
Nodeptr Mynode() const
{
return (_Ptr);
}
protected:
Nodeptr _Ptr;
}; // end iterator
//
// const_iterator
//
class const_iterator : public iterator
{
public:
// Constructors
const_iterator()
{
}
const_iterator(Nodeptr __P)
: iterator(__P)
{
}
const_iterator(const iterator& __X)
: iterator(__X)
{
}
const _Ty& operator *() const
{
return (Acc::Value(_Ptr)); //error: line 148 `_Ptr' was not declared in this scope
}
// Prefix ++
const_iterator& operator ++()
{
_Ptr = Acc::Next(_Ptr); //error: line 154 `_Ptr' was not declared in this scope
return (*this);
}
// Postfix ++
const_iterator operator ++(int)
{
iterator _Tmp = *this;
++*this;
return (_Tmp);
}
// Prefix --
const_iterator& operator --()
{
_Ptr = Acc::Prev(_Ptr); //error: line 169 `_Ptr' was not declared in this scope
return (*this);
}
// Postfix --
const_iterator operator --(int)
{
iterator _Tmp = *this;
--*this;
return (_Tmp);
}
bool operator ==(const const_iterator& __X) const
{
return (_Ptr == __X._Ptr); //error: line 183 `_Ptr' was not declared in this scope
}
bool operator !=(const const_iterator& __X) const
{
return (!(*this == __X));
}
}; // end const_iterator
I get below errors with gcc 3.4.6:
Code:
../include/list.h:148: error: `_Ptr' was not declared in this scope
../include/list.h: In member function `utils::list<_Ty>::const_iterator& utils::list<_Ty>::const_iterator::operator++()':
../include/list.h:154: error: `_Ptr' was not declared in this scope
../include/list.h: In member function `utils::list<_Ty>::const_iterator& utils::list<_Ty>::const_iterator::operator--()':
../include/list.h:169: error: `_Ptr' was not declared in this scope
../include/list.h: In member function `bool utils::list<_Ty>::const_iterator::operator==(const utils::list<_Ty>::const_iterator&) const':
../include/list.h:183: error: `_Ptr' was not declared in this scope
It will be highly appreciated if someone can please shed some light on this?
Re: Template declaration issue with the scope
Where, where is _Ptr declared? I don't see any includes, I assume that it's in the macro, but where was the macro defined?
Why are you using compilers that are so out of date? Is there a reason that you can't upgrade to 4.2 or 4.4?
Re: Template declaration issue with the scope
I am using RHL4 and want to get this compiled using gcc 3.4.6.
If I am not mistaking, _Ptr is already defined in the code snippet that I added earlier. So I guess no need of any other include file. Same code gets compiled on gcc 2.3.
Code:
protected:
Nodeptr _Ptr;
}; // end iterator
Please note that above _Ptr declaration is in class "iterator". However, I am getting errors at lines 148, 154, 169, 183 in the class "const_iterator". Class "const_iterator" is publicly inheriting from class "iterator". I am really confused as to what is causing compiler errors here?
Re: Template declaration issue with the scope
Here is the complete list.h file:
Code:
// list standard header
#ifndef __UTILS_LIST__
#define __UTILS_LIST__
NAMESPACE_BEGIN(utils)
//
// template class list
//
template <class _Ty>
class list
{
protected:
//
// struct Node & Nodeptr
// - Each element in the list is a struct Node
//
struct Node;
friend struct Node;
typedef Node *Nodeptr;
public:
//
// This is what is being defined (the type of 'this')
//
typedef list<_Ty> _Myt;
//
// Forward & friend declarations for the iterators
//
class iterator;
friend class iterator;
class const_iterator;
friend class const_iterator;
//
// iterator()
//
class iterator
{
public:
// Constructors
iterator()
{
}
iterator(Nodeptr __P)
: _Ptr(__P)
{
}
_Ty &operator *() const
{
return Acc::Value(_Ptr);
}
// Prefix ++
iterator& operator ++()
{
_Ptr = Acc::Next(_Ptr);
return (*this);
}
// Postfix ++
iterator operator ++(int)
{
iterator _Tmp = *this;
++*this;
return (_Tmp);
}
// Prefix --
iterator& operator --()
{
_Ptr = Acc::Prev(_Ptr);
return (*this);
}
// Postfix --
iterator operator --(int)
{
iterator _Tmp = *this;
--*this;
return (_Tmp);
}
bool operator ==(const iterator& __X) const
{
return (_Ptr == __X._Ptr);
}
bool operator !=(const iterator& __X) const
{
return (!(*this == __X));
}
Nodeptr Mynode() const
{
return (_Ptr);
}
protected:
Nodeptr _Ptr;
}; // end iterator
//
// const_iterator
//
class const_iterator : public iterator
{
public:
// Constructors
const_iterator()
{
}
const_iterator(Nodeptr __P)
: iterator(__P)
{
}
const_iterator(const iterator& __X)
: iterator(__X)
{
}
const _Ty& operator *() const
{
return (Acc::Value(_Ptr));
}
// Prefix ++
const_iterator& operator ++()
{
_Ptr = Acc::Next(_Ptr);
return (*this);
}
// Postfix ++
const_iterator operator ++(int)
{
iterator _Tmp = *this;
++*this;
return (_Tmp);
}
// Prefix --
const_iterator& operator --()
{
_Ptr = Acc::Prev(_Ptr);
return (*this);
}
// Postfix --
const_iterator operator --(int)
{
iterator _Tmp = *this;
--*this;
return (_Tmp);
}
bool operator ==(const const_iterator& __X) const
{
return (_Ptr == __X._Ptr);
}
bool operator !=(const const_iterator& __X) const
{
return (!(*this == __X));
}
}; // end const_iterator
//
// list<> constructors()
//
explicit list()
: _Head(Buynode()), _Size(0)
{
}
explicit list(size_t __N, const _Ty& _V = _Ty())
: _Head(Buynode()), _Size(0)
{
insert(begin(), __N, _V);
}
list(const _Myt& __X)
: _Head(Buynode()), _Size(0)
{
insert(begin(), __X.begin(), __X.end());
}
// Destructor
~list()
{
erase(begin(), end());
Freenode(_Head);
_Head = 0, _Size = 0;
}
_Myt& operator =(const _Myt& __X)
{
if (this != &__X)
{
iterator _F1 = begin();
iterator _L1 = end();
const_iterator _F2 = __X.begin();
const_iterator _L2 = __X.end();
for (; _F1 != _L1 && _F2 != _L2; ++_F1, ++_F2)
*_F1 = *_F2;
erase(_F1, _L1);
insert(_L1, _F2, _L2);
}
return (*this);
}
//
// Return const and non-const iterators
//
iterator begin()
{
return (iterator(Acc::Next(_Head)));
}
const_iterator begin() const
{
return (const_iterator(Acc::Next(_Head)));
}
iterator end()
{
return (iterator(_Head));
}
const_iterator end() const
{
return (const_iterator(_Head));
}
size_t size() const
{
return (_Size);
}
bool empty() const
{
return (size() == 0);
}
_Ty front()
{
return (*begin());
}
const _Ty front() const
{
return (*begin());
}
_Ty back()
{
return (*(--end()));
}
const _Ty back() const
{
return (*(--end()));
}
iterator push_front(const _Ty& __X)
{
return insert(begin(), __X);
}
// pop_front now returns the 'popped' element
_Ty pop_front()
{
_Ty t = *begin();
erase(begin());
return t;
}
iterator push_back(const _Ty& __X)
{
return insert(end(), __X);
}
// pop_back now returns the 'popped' element
_Ty pop_back()
{
_Ty t = *--end();
erase(end());
return t;
}
void assign(const_iterator __F, const_iterator __L)
{
erase(begin(), end());
insert(begin(), __F, __L);
}
void assign(size_t __N, const _Ty& __X = _Ty())
{
erase(begin(), end());
insert(begin(), __N, __X);
}
iterator insert(iterator __P, const _Ty& __X = _Ty())
{
Nodeptr __S = __P.Mynode();
Nodeptr _tmp = Buynode(__S, Acc::Prev(__S));
if (_tmp)
{
Acc::Prev(__S) = _tmp;
__S = Acc::Prev(__S);
Acc::Next(Acc::Prev(__S)) = __S;
Acc::Value(__S) = __X;
++_Size;
return (iterator(__S));
}
return (iterator(0));
}
void insert(iterator __P, size_t __M, const _Ty& __X)
{
for (; 0 < __M; --__M)
insert(__P, __X);
}
void insert(iterator __P, const _Ty *__F, const _Ty *__L)
{
for (; __F != __L; ++__F)
insert(__P, *__F);
}
void insert(iterator __P, const_iterator __F, const_iterator __L)
{
for (; __F != __L; ++__F)
insert(__P, *__F);
}
iterator erase(iterator __P)
{
Nodeptr __S = (__P++).Mynode();
Acc::Next(Acc::Prev(__S)) = Acc::Next(__S);
Acc::Prev(Acc::Next(__S)) = Acc::Prev(__S);
Freenode(__S);
--_Size;
return (__P);
}
iterator erase(iterator __F, iterator __L)
{
while (__F != __L)
erase(__F++);
return (__F);
}
void clear()
{
erase(begin(), end());
}
void remove(const _Ty& _V)
{
iterator __L = end();
for (iterator __F = begin(); __F != __L; )
if (*__F == _V)
erase(__F++);
else
++__F;
}
void replace(const _Ty &Old, const _Ty &New)
{
iterator __L = end();
for (iterator __F = begin(); __F != __L; )
if (*__F == Old)
{
*__F++ = New;
}
else
++__F;
}
protected:
struct Node
{
struct Node *_Next;
struct Node *_Prev;
_Ty _Value;
};
//
// struct Acc
// - This is used to access the members of the Node struct above.
// - XXX: Why is a separate struct needed?
//
struct Acc;
friend struct Acc;
struct Acc
{
typedef Nodeptr &Nodepref;
// Next()
static Nodepref Next(Nodeptr __P)
{
return ((Nodepref)(*__P)._Next);
}
// Prev()
static Nodepref Prev(Nodeptr __P)
{
return ((Nodepref)(*__P)._Prev);
}
// Value()
static _Ty& Value(Nodeptr __P)
{
return ((_Ty&)(*__P)._Value);
}
};
// Allocate a new node
Nodeptr Buynode(Nodeptr Narg = 0, Nodeptr Parg = 0)
{
Nodeptr S = (Nodeptr) calloc(1, sizeof (Node));
if (S)
{
Acc::Next(S) = Narg != 0 ? Narg : S;
Acc::Prev(S) = Parg != 0 ? Parg : S;
}
return (S);
}
void Freenode(Nodeptr S)
{
free(S);
}
//
// List data:
//
Nodeptr _Head;
size_t _Size;
}; // end class list
NAMESPACE_END
#endif /* __UTILS_LIST__ */
Hope this helps someone finding the solution of the errors that I am getting.
Please help.
Re: Template declaration issue with the scope
I don't have GCC, but it compiles fine on VS2008 with a couple of minor changes (nothing to do with your problem)
Re: Template declaration issue with the scope
identifiers with a double underscore in them, and starting with an underscore followed by a capital letter are reserved for the implementation. If you are not writing a compiler or libraries to be supplied with a compiler then a lot of your identifiers are illegal. Prefer trailing underscores to leading underscores. Never use double underscores.
Re: Template declaration issue with the scope
I changed the names; but still no effect. The same errors are still coming. :(
Re: Template declaration issue with the scope
Could you show us the complete .h file using this, as well as the complete error messages. I feel we are missing something.
Re: Template declaration issue with the scope
I guess the name lookup is a bit weird in this case. Maybe try using
Code:
const _Ty& operator *() const
{
return (Acc::Value(iterator::_Ptr));
}
Re: Template declaration issue with the scope
Thanks a lot Yves M. It did solve the issue.