Topic: Can't a template class be a friend of itself ?
Author: jasonchen@my-deja.com
Date: 2000/08/03 Raw View
Hi,
I encountered a problem with friend
declaration while implementing
a STL-like list class. When I compile the same
code under VC++, SGI CC
and g++, I got different results. Specifically,
VC++ and SGI CC allows
a friend class declaration to itself, but g++
doesn't seem to like it.
Please see the following code:
template<class T> class list; // forward
declaration
template<class T, class Ref, class Ptr> class
_list_iterator {
public:
typedef _list_iterator<T, T&, T*> iterator;
typedef _list_iterator<T, const T&, const T*>
const_iterator;
friend class list<T>; // so it can use the
private constructor
friend class _list_iterator<T, const T&,
const T*>;
// so const_iterator's constructor can
access iterator's private field.
private:
_list_node_base *cursor;
_list_iterator(_list_node_base *p) : cursor
(p) {}
public:
_list_iterator() : cursor(NULL) {}
// allow conversion from iterator to
const_iterator
_list_iterator(const iterator& iter) : cursor
(iter.cursor) {}
.......
};
template<class T> class list {
.....
private:
node root;
public:
typedef _list_iterator<T, T&, T*> iterator;
typedef _list_iterator<T, const T&, const T*>
const_iterator;
iterator begin() { return iterator
(root.next); }
const_iterator begin() const { return
const_iterator(root.next); }
......
};
This code tries to hide the details of
_list_iterator therefore
two friend declarations are used to grant
accesses:
(1) For list<T> to construct iterator or
const_iterator
(2) For a const_iterator to access iterator's
private field, thus making
it possible to convert an iterator to
const_iterator.
Now the problem happens with this friend
declaration in the
_list_iterator template:
friend class _list_iterator<T, const T&,
const T*>;
While instantiating _list_iterator<T, const
T&, const T*> (by
list<T>::const_iterator), this declaration is
essentially trying
to make friends with itself. The result I got
was:
VC++ 6.0 : code compiles without error or
warning
SGI CC 7.30: code compiles with warning saying
pointless friend
declaration while instantiating
_list_iterator<int, const int&,
const int*>
g++ 2.95 : code won't compile. the error
was implicit friend
declaration with itself
So I did a little test, trying to
instantiate obj<int> by the following
class template:
template<class T> obj {
friend class obj<T>; // same result as
above, VC++/SGI works, g++ error
friend class obj<int>; // compiles on all
three compilers. SGI CC 7.30
// gave the same
warning as above
private:
T obj;
....
};
So it seems that it is okay to declare a
friend class to itself
as long as the declaration doesn't involve the
template argument. But
I am confused if g++'s behavior is correct. It
seems to me that a
friend declaration to itself should be allowed,
and in my case I needed
it to keep the details of _list_iterator class
private.
Any comments are appreciated.
// Jason Chen //
// Electronics For Imaging, Inc. //
// E-MAIL: Jason.Chen@efi.com //
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]