Topic: Templates & friends
Author: jamshid@emx.cc.utexas.edu (Jamshid Afshar)
Date: 21 Jun 1993 13:58:37 -0500 Raw View
In article <C8Lpp2.6Lx@abacus.be> mdu@abacus.be (Marc Duponcheel) writes:
>I use the construct as follows :
>There is a SmartObj class which has protected
>methods Incr() ans Decr() to update the number
>of SmartPtr 's referencing to it.
>All the SmartPtr<T> classes are friend (they update
>the counters in constructors, destructors etc...)
Anyone know if the following will be legal? Can a template class or
function be made a friend while partially constraining some of the
template-arguments?
template<class T> class Foo;
template<class T1, class T2>
int f(const Foo<T1>&, const Foo<T2>&);
template<class T> class Foo {
template<class T2> friend int f(const Foo<T>&, const Foo<T2>&);
template<class T1> friend int f(const Foo<T1>&, const Foo<T>&);
// only want `f()'s taking Foo<T> to be a `friend'
int i;
//...
};
template<class T1, class T2>
int f(const Foo<T1>& a, const Foo<T2>& b)
{ return a.i + b.i; }
Jamshid Afshar
jamshid@emx.utexas.edu
Author: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Date: Wed, 9 Jun 1993 05:07:05 GMT Raw View
grumpy@cbnewse.cb.att.com (Paul J Lucas) writes:
>From article <1993Jun8.111313.5514@unix.brighton.ac.uk>, by je@unix.brighton.ac.uk (John English):
>> How do I make all instantiations of a template class friends of a
>> non-template class? Specifically, I want something like:
>>
>> template<class T> class X {
>> ...
>> };
>>
>> class Y {
>> friend class X; // X<anything> is a friend of Y
>> ...
>> };
>>
>> Borland C++ moans at me if I try to access any Y privates from an X
>> member function. Is it me, or is it BC++?
>
> template<class T> friend class X<T>;
>
> This is covered in C++ books, you know.
By my reading of the ARM, this is illegal: "A template declaration may
only appear at global scope" (14.1), whereas a friend declaration such as
your suggestion above has to occur inside in class scope.
--
Fergus Henderson This .signature virus might be
fjh@munta.cs.mu.OZ.AU getting old, but you still can't
consistently believe it unless you
Linux: Choice of a GNU Generation copy it to your own .signature file!
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Wed, 9 Jun 1993 07:22:45 GMT Raw View
In article <9316015.574@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
+grumpy@cbnewse.cb.att.com (Paul J Lucas) writes:
+
+>From article <1993Jun8.111313.5514@unix.brighton.ac.uk>, by je@unix.brighton.ac.uk (John English):
+>> How do I make all instantiations of a template class friends of a
+>> non-template class? Specifically, I want something like:
+>>
+>> template<class T> class X {
+>> ...
+>> };
+>>
+>> class Y {
+>> friend class X; // X<anything> is a friend of Y
+>> ...
+>> };
+>>
+>> Borland C++ moans at me if I try to access any Y privates from an X
+>> member function. Is it me, or is it BC++?
+>
+> template<class T> friend class X<T>;
+>
+> This is covered in C++ books, you know.
+
+By my reading of the ARM, this is illegal: "A template declaration may
+only appear at global scope" (14.1), whereas a friend declaration such as
+your suggestion above has to occur inside in class scope.
See Lippman, page 361, middle example:
class Foo {
template <class T> friend class Bar;
// ...
};
--
// Ron ("Loose Cannon") Guilmette uucp: ...uunet!lupine!segfault!rfg
//
// "On the one hand I knew that programs could have a compelling
// and deep logical beauty, on the other hand I was forced to
// admit that most programs are presented in a way fit for
// mechanical execution, but even if of any beauty at all,
// totally unfit for human appreciation."
// -- Edsger W. Dijkstra
Author: je@unix.brighton.ac.uk (John English)
Date: Wed, 9 Jun 1993 17:19:53 GMT Raw View
rfg@netcom.com (Ronald F. Guilmette) writes:
: +>From article <1993Jun8.111313.5514@unix.brighton.ac.uk>, by je@unix.brighton.ac.uk (John English):
: +>> How do I make all instantiations of a template class friends of a
: +>> non-template class? [ ... ]
:
: See Lippman, page 361, middle example:
:
: class Foo {
: template <class T> friend class Bar;
: // ...
: };
Tried that too... Borland C++ moans "Declaration terminated incorrectly".
Is Lippmann wrong or Borland? Looking at Stroustrup & the ARM, there
doesn't seem to be anything in the templates bits about this sort of
friendship, or in the friends bits about templates. Certainly everything
else I can find in those two estimable volumes suggests that the magic word
"template" is a no-no except at file scope. Any more ideas?
--
-------------------------------------------------------------------------------
John English | "There are basically two types of dicks,
Dept. of Computing | hard dicks and floppy dicks."
University of Brighton | -- from a student essay on storage media
E-mail: je@unix.brighton.ac.uk | "Disks are divided into sex & tractors."
Fax: 0273 642405 | -- from one of my lectures (on a bad day)
-------------------------------------------------------------------------------
Author: pete@borland.com (Pete Becker)
Date: Wed, 9 Jun 1993 17:43:54 GMT Raw View
In article <rfgC8CF5y.GEH@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>+>>
>+>> Borland C++ moans at me if I try to access any Y privates from an X
>+>> member function. Is it me, or is it BC++?
>+>
>+> template<class T> friend class X<T>;
>+>
>+> This is covered in C++ books, you know.
>+
>+By my reading of the ARM, this is illegal: "A template declaration may
>+only appear at global scope" (14.1), whereas a friend declaration such as
>+your suggestion above has to occur inside in class scope.
>
>See Lippman, page 361, middle example:
>
> class Foo {
> template <class T> friend class Bar;
> // ...
> };
>
Whoa, slow down! Lippman is a secondary source. The ARM is a primary
source. When a secondary source and a primary source disagree, the primary
source wins. It is not legal to declare a template anywhere but in global
scope. That doesn't mean that you can't refer to a template that hasn't been
defined yet, but in order to do so you have to provide a forward reference:
template <class T> class Bar; // forward reference
class Foo
{
friend Bar; // still illegal, but for a different reason
};
The attempt to make Bar a friend is illegal because Bar is neither the name of
a class nor the name of a function. Those are the only things that can be
friends.
-- Pete
Author: g2devi@cdf.toronto.edu (Deviasse Robert N.)
Date: 10 Jun 93 00:55:27 GMT Raw View
Author: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Date: Thu, 10 Jun 1993 06:51:09 GMT Raw View
rfg@netcom.com (Ronald F. Guilmette) writes:
>fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
>
>+By my reading of the ARM, this is illegal: "A template declaration may
>+only appear at global scope" (14.1), whereas a friend declaration such as
>+your suggestion above has to occur inside in class scope.
>
>See Lippman, page 361, middle example:
>
> class Foo {
> template <class T> friend class Bar;
> // ...
> };
So we should send Lippman some mail informing him of the error in his book? :-)
Lippman is not the definition of the language, and neither is Cfront
for that matter.
--
Fergus Henderson This .signature virus might be
fjh@munta.cs.mu.OZ.AU getting old, but you still can't
consistently believe it unless you
Linux: Choice of a GNU Generation copy it to your own .signature file!
Author: grumpy@cbnewse.cb.att.com (Paul J Lucas)
Date: Thu, 10 Jun 1993 13:45:01 GMT Raw View
Author: je@unix.brighton.ac.uk (John English)
Date: Fri, 11 Jun 1993 00:41:36 GMT Raw View
grumpy@cbnewse.cb.att.com (Paul J Lucas) writes:
: This presupposes that you previously declared at global scope
:
: template<class T> class X;
:
: either as a forward declaration (above) or the entire class.
The entire class was declared up front (see original post).
: The friend declaration is a reference to the global one. The
: spirit of what the ARM *means* is that a "new" template, i.e.,
: previously unseen, declaration is illegal in class scope.
Hum, obviously the guys at Borland don't talk to the same spirit medium
as you do. Is the *spirit* of a meaning adequate to base an ANSI standard
on? What I really need is a pointer to page X of the ARM and a clear
statement of intent, rather than "oh what they really meant when they
wrote this was..." <we haven't considered this one> <we don't know>
<let's see what the compiler writers think> etc. etc.
As it is, we get 70-proof compilers as a result... :-)
--
-------------------------------------------------------------------------------
John English | "There are basically two types of dicks,
Dept. of Computing | hard dicks and floppy dicks."
University of Brighton | -- from a student essay on storage media
E-mail: je@unix.brighton.ac.uk | "Disks are divided into sex & tractors."
Fax: 0273 642405 | -- from one of my lectures (on a bad day)
-------------------------------------------------------------------------------
Author: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Date: Fri, 11 Jun 1993 02:30:33 GMT Raw View
grumpy@cbnewse.cb.att.com (Paul J Lucas) writes:
>From article <1993Jun9.161018.29766@unix.brighton.ac.uk>, by je@unix.brighton.ac.uk (John English):
>> grumpy@cbnewse.cb.att.com (Paul J Lucas) writes:
>> : From article <1993Jun8.111313.5514@unix.brighton.ac.uk>, by je@unix.brighton.ac.uk (John English):
>> : > How do I make all instantiations of a template class friends of a
>> : > non-template class?
>> :
>> : template<class T> friend class X<T>;
>> :
>> : This is covered in C++ books, you know.
>>
>> Errm... sorry, that's even more illegal than what I tried. As you say, it
>> *is* covered in C++ books, but what they say is you can't declare templates
>> except at global scope. RTFM yourself?
>
> It's in Lippman's book and mine. I already reponsed that
> the ARM *means* that *new* template declarations must be
> at file scope.
Well, I'd be happier if the ARM or the working papers actually *said* what you
(and Lippman, and Cfront :-) think they mean.
--
Fergus Henderson This .signature virus might be
fjh@munta.cs.mu.OZ.AU getting old, but you still can't
consistently believe it unless you
Linux: Choice of a GNU Generation copy it to your own .signature file!
Author: marc@offline.be (Marc Duponcheel)
Date: 10 Jun 93 23:52:03 PST Raw View
In article <1993Jun9.174354.1236@borland.com> (dated Wed, 9 Jun 1993 17:43:54 GMT) Pete Becker (pete@borland.com) wrote:
> template <class T> class Bar; // forward reference
> class Foo
> {
> friend Bar; // still illegal, but for a different reason
> };
> The attempt to make Bar a friend is illegal because Bar is neither the name of
> a class nor the name of a function. Those are the only things that can be
> friends.
> -- Pete
Does this mean that OFFICIALLY you cannot make all Bar<T> classes friend at once
(similar for template functions ...) ?
cfront does allow it, so cfront is wrong ?
-- marc.
Author: grumpy@cbnewse.cb.att.com (Paul J Lucas)
Date: Sun, 13 Jun 1993 16:47:34 GMT Raw View
Author: pete@borland.com (Pete Becker)
Date: Sun, 13 Jun 1993 18:45:14 GMT Raw View
In article <marc.04i0@offline.be> marc@offline.be (Marc Duponcheel) writes:
>> The attempt to make Bar a friend is illegal because Bar is neither the name of
>> a class nor the name of a function. Those are the only things that can be
>> friends.
>> -- Pete
>
>Does this mean that OFFICIALLY you cannot make all Bar<T> classes friend at once
>(similar for template functions ...) ?
>
>cfront does allow it, so cfront is wrong ?
>
Depends on what you mean by "OFFICIALLY". My reading of the ARM says
that you cannot make all instances of a class template friends of some other
class. On the other hand, that doesn't sound like a totally unreasonable thing
to do (although I suspect that needing to do it would usually indicate a
design problem), so it's possible that the ANSI/ISO committee will change the
language in the working paper to allow it.
Even if it's illegal, it's not wrong to allow it. The C++ working paper
doesn't have any language yet on what implementations are allowed to do with
illegal programs, but it will probably end up with a rule similar to the rule
in ANSI C, which is that the compiler must issue a diagnostic, then can do
whatever it pleases. If that's the route that the C++ standard takes, cfront
and other compilers would be free to allow this as an extenstion provided
they give you some sort of message when you use it.
-- Pete
Author: mdu@abacus.be (Marc Duponcheel)
Date: Mon, 14 Jun 1993 07:48:37 GMT Raw View
In article <1993Jun13.184514.26974@borland.com> dated Sun, 13 Jun 1993 18:45:14 GMT, Pete Becker (pete@borland.com) wrote:
: Depends on what you mean by "OFFICIALLY". My reading of the ARM says
: that you cannot make all instances of a class template friends of some other
: class. On the other hand, that doesn't sound like a totally unreasonable thing
: to do (although I suspect that needing to do it would usually indicate a
: design problem), so it's possible that the ANSI/ISO committee will change the
: language in the working paper to allow it.
I use the construct as follows :
There is a SmartObj class which has protected
methods Incr() ans Decr() to update the number
of SmartPtr 's referencing to it.
All the SmartPtr<T> classes are friend (they update
the counters in constructors, destructors etc...)
-- marc.
ABACUS consultants +32 (0)2 772.22.46
mdu@abacus.be (Marc Duponcheel)
--
ABACUS consultants +32 (0)2 772.22.46
mdu@abacus.be (Marc Duponcheel)