Topic: can a template be friend?


Author: Benko Pal <benko@arta.geo.sztaki.hu>
Date: Thu, 13 Dec 2001 07:20:19 CST
Raw View
and a partial specialisation?

is the following valid c++?

template <typename T>
class a
{
  class inner
  {
    template <typename U>
    friend class a;
  };
};

template <typename T>
class a<a<T> >
{
  class inner
  {
    friend class a;
  };
};

template <>
class a<int>
{
  class inner
  {
    template <typename T>
    friend class a<a<T> >;
  };
};

I hope the intended semantics is clean.  If the above is not valid
code, can it be done and how?

(gcc-3.0.2 accepts the first and rejects the other ones.)

Thanks,

Pal Benko

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Richard Smith" <richard@ex-parrot.com>
Date: Thu, 13 Dec 2001 13:23:10 CST
Raw View
"Benko Pal" <benko@arta.geo.sztaki.hu> wrote in message
news:iqellzpmwy.fsf@arta.geo.sztaki.hu...
> and a partial specialisation?
>
> is the following valid c++?
>
> template <typename T>
> class a
> {
>   class inner
>   {
>     template <typename U>
>     friend class a;
>   };
> };

This one seems fine.  You are declaring all possible instantiations of a<T>
to be friends of a<T>::inner. Thus a<short> is a friend of a<long>::inner.
Note that this is irrespective of whether they use the primary tempalte or a
later specialisation, so, for example, a< a<short> > is also a friend of
a<long>::inner.

> template <typename T>
> class a<a<T> >
> {
>   class inner
>   {
>     friend class a;
>   };
> };

This too looks fine, although this does something rather different to the
one above.  This declares a< a<T> > to be a friend of a< a<T> >::inner, but
only for the same type, T.  Thus a< a<short> > is not a friend of a< a<long>
>::inner; the only friend of a< a<long> >::inner is only a< a<long> >.  This
is a classic example of a nested class granting friendship to the enclosing
one.

> template <>
> class a<int>
> {
>   class inner
>   {
>     template <typename T>
>     friend class a<a<T> >;
>   };
> };

This is not legal.  Here you are declaring a< a<T> > for any T to be a
friend of a<int>.  This is specifically disallowed by paragraph 14.5.3/9.
You can however either declare all instantiations of a to be friends of
a<int>::inner, or just some specific instantiations.  For example

    template <>
    class a<int>
    {
      class inner
      {
        template <typename T>
        friend class a;
      };
    };

or

    template <>
    class a<int>
    {
      class inner
      {
        friend class a< a<int> >;
      };
    };

are both legal, and might do what you intended.

--
Richard Smith


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]