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)