Topic: Specifying a templated class as a friend
Author: Kresimir Fresl <fresl@grad.hr>
Date: 1997/05/01 Raw View
Robert P. Krajewski wrote:
> I know that templates in C++ have been in flux for some time,
> and now it has bit me. Since this code is supposed to keep
> working, it's a nuts-and-bolts question. And I think it's a
> standards question since there seems to be a hole in the
> latest ANSI draft I've seen (December 1996).
...
> ... we have something like:
>
> template<class ct> class String {
> ...
> friend class WriteLock<ct>; // friend declaration (and forward)
> ...
> };
>
> template<class ct> class WriteLock {
> ...
> WriteLock(String<ct> & aString); // constructor
> ...
> };
Class WriteLock<ct> should be `forward declared':
template <class ct> class WriteLock; // <----
template <class ct> class String {
friend class WriteLock<ct>;
public:
String (ct c) : c_(c) { cout << "String: " << c_ << endl; }
private:
ct c_;
};
template <class ct> class WriteLock {
public:
WriteLock (String<ct> const& s) {
cout << "WriteLock: " << s.c_ << "\n";
}
};
main () {
String<char> s1 ('c');
WriteLock<char> w1 (s1);
}
(Unfortunately, I do not know if this will work with
M$ VC++.)
> From what I was reading in the newest draft about templates,
> it doesn't look like what I want to do (specify a not-yet-defined
> templated class as a friend of templated class) is possible;
Class can be `not-yet-defined', but, as I said, it should be
`forward declared', that is, its name should be declared
before friend declaration.
> it only seems possible to specify templated functions
> as friends of non-templated classes. This is in section
> 14.5.3 (template.friend) of the December ANSI/ISO draft:
...
> And the syntax is odd, but I tried it:
>
> template<ct> friend class WriteLock;
>
> ...and the Microsoft compiler spit back a different, cryptic
> error message at me.
It should be
template <class ct> friend class WriteLock;
^^^^^
But, now
// with or without
template <class ct> class WriteLock;
template <class ct> class String {
template <class ct> friend class WriteLock;
// as in previous example
};
// rest of the code as in previous example
Comeau C++ v4.0 gives a warning:
... warning: declaration of "ct" hides template parameter
template <class ct> friend class WriteLock;
^
This means that
template <class ct> friend class WriteLock;
^^
is the same as
template <class ct1> friend class WriteLock;
^^^
(which compiles without a warning), that is, with this
form of declaration template parameters in two classes are
unrelated (eg. WriteLock<char> can be friend of
String<wchar_t>).
> Am I misreading the spec ? Perhaps 14.5.3 only clarifies
> certain cases but doesn't preclude what I'm doing, or maybe
> it does.
AFAICS, it doesn't.
> But what makes me pessimistic is that it shows no example
> of a friend template class being declared using one of a
> defining classes' parameters.
Well, I think that there really is a lack of examples in
the Draft, particularly with templates. I had similar
problems (and some of them are still unresolved); for
more info you can read the thread `friend templates' in
comp.lang.c++.moderated. (In this thread you can find
Greg Comeau's explanation why in the second case there is
not need for `forward declaration' of WriteLock<ct>.)
K. Fresl
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]