A template class(tstack class) has a singly-linked list "struct" declaration in private section. Another template class(tstackIterator) - iterator class is declared and defined in global space. If the iterator template class trys to get access to the linked list structure inside the previous class with a friend statement declared in the previous class, it does not work. It behaves in much the same way as without friend declaration. The following code shows this: //: TSTACK.H -- Stack using templates #ifndef TSTACK_H_ #define TSTACK_H_
// Some implementations require this: template<class T> class tstackIterator; template<class T> class tstack { struct link { T* data; link* next; link(T* Data, link* Next){ data = Data; next = Next; } } * head; int owns; public: tstack(int Owns = 1) : head(0), owns(Owns) {} ~tstack(); void push(T* Data) { head = new link(Data,head); } T* peek() const { return head->data; } T* pop(); int Owns() const { return owns; } void Owns(int newownership) { owns = newownership; } friend class tstackIterator<T>; }; template<class T> T* tstack<T>::pop() { if(head == 0) return 0; T* result = head->data; link* oldHead = head; head = head->next; delete oldHead; return result; } template<class T> tstack<T>::~tstack() { link* cursor = head; while(head) { cursor = cursor->next; // Conditional cleanup of data: if(owns) delete head->data; delete head; head = cursor; } } template<class T> class tstackIterator { //////////////////////////////////// tstack<T>::link* p; // this is line 68 // when it is compiled, g++ 3.4.1 give some error message but it does not make //sense in terms of languae. but the version g++ (GCC) 3.2.3 20030502 works fine // except that it gives a warning saying "tstack.h:68: warning: `typename //tstack<T>::link' is implicitly a typename" //The Error message is attached to the bottom /////////////////////////////////// public: tstackIterator(const tstack<T>& tl) : p(tl.head) {} tstackIterator(const tstackIterator& tl) : p(tl.p) {} // operator++ returns boolean indicating end: int operator++() { if(p->next) p = p->next; else p = 0; // Indicates end of list return int(p); } int operator++(int) { return operator++(); } // Smart pointer: T* operator->() const { if(!p) return 0; return p->data; } T* current() const { if(!p) return 0; return p->data; } // int conversion for conditional test: operator int() const { return p ? 1 : 0; } }; #endif // TSTACK_H_ //////////////////////////////////////////// the compiler complaints are as follows: In file included from tstktst.cpp:2: ../14/tstack.h:68: error: expected `;' before '*' token ../14/tstack.h: In constructor `tstackIterator<T>::tstackIterator(const tstack<T>&)': ../14/tstack.h:71: error: class `tstackIterator<T>' does not have any field named `p' ../14/tstack.h: In copy constructor `tstackIterator<T>::tstackIterator(const tstackIterator<T>&)': ../14/tstack.h:73: error: class `tstackIterator<T>' does not have any field named `p' ../14/tstack.h: In member function `int tstackIterator<T>::operator++()': ../14/tstack.h:76: error: `p' undeclared (first use this function) ../14/tstack.h:76: error: (Each undeclared identifier is reported only once for each function it appears in.) ../14/tstack.h: In member function `T* tstackIterator<T>::operator->() const': ../14/tstack.h:84: error: `p' undeclared (first use this function) ../14/tstack.h: In member function `T* tstackIterator<T>::current() const': ../14/tstack.h:88: error: `p' undeclared (first use this function) ../14/tstack.h: In member function `tstackIterator<T>::operator int() const': ../14/tstack.h:92: error: `p' undeclared (first use this function) -- Summary: friend funtion inside a template class seems to have a problem Product: gcc Version: 3.4.1 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: max656 at hotmail dot com CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19188