Topic: Can't a template class be a friend to itself ?
Author: Jason.Chen@efi.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, i.e. VC++/SGI CC
// 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 ]