Topic: template friend functions


Author: Thomas Kunert <kunert@physik.tu-dresden.de>
Date: 2000/09/17
Raw View
Anthony Williams wrote:

 > > > template<typename T>
 > > > class MyClass
 > > > {
 > > >   template<typename U>
 > > >   friend void func(MyClass<T> mc,U data);
 > > > };
 > > >
 > > > How can I define this function outside the class template?
 > > >
 > > > I tried:
 > > >
 > > > template<typename T>
 > > > template<typename U>
 > > > void func(MyClass<T> mc,U data)
 > > > {}
 > >
 > > This is ill-formed. If that has worked, your compiler is broken.
 >
 > This is the syntax for a member template - see 14.5.2 of the
standard. If
 > func had been a member function rather than a friend, then
 >
 > template<typename T>
 > template<typename U>
 > void MyClass<T>::func(MyClass<T> mc,U data)
 > {}
 >
 > should work.

Right. Unfortunately, here we don't have a member but a friend.

>
> It works if it is declared and defined as part of the friend declaration in
> the class template, and does exactly what I expect:
>
> template<typename T>
> class MyClass
> {
>   template<typename U>
>   friend void func(MyClass<T> mc,U data)
>   {
>   // function body here
>   }
> };
>

OK, got it now.
If you define it outside the class template, you have to define this
function for each T seperately, since T is not a template parameter for
the function, i.e. you write

template <typename U>
void func(MyClass<int>, U data ){ /*...*/}

template <typename U>
void func(MyClass<char>, U data ){ /*...*/}

That means you better define it inside the class.

Sorry for confusion
Thomas

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ 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              ]





Author: Thomas Kunert <kunert@physik.tu-dresden.de>
Date: 2000/09/14
Raw View
Anthony Williams wrote:
>
> I have a class template, and I want to declare a friend function that
> performs
> some operation on this class. The problem is, I want this friend
> function to be
> a template
>
> template<typename T>
> class MyClass
> {
>   template<typename U>
>   friend void func(MyClass<T> mc,U data);

That probably does not do what you want. Here you declare a function
template with *one* template parameter, and with two arguments. The
first argument type is MyClass<T> and the second one is defined through
the template parameter.

> };
>
> How can I define this function outside the class template?
>
> I tried:
>
> template<typename T>
> template<typename U>
> void func(MyClass<T> mc,U data)
> {}

This is ill-formed. If that has worked, your compiler is broken.

>
> and
>
> template<typename T,typename U>
> void func(MyClass<T> mc,U data)
> {}
>

This declares an unrelated function template with two template
parameters.
What you probably want is a function template with two template
parameters

template<typename A,typename B>
void func(MyClass<A> mc,B data)
{}

that is a friend of myclass<T> when A and T are the same type. That is
not possible in c++, a friend can be either the full function template
or some specialization of it.

Hope this helps,
Thomas

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ 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              ]





Author: "Anthony Williams" <anthony_w.geo@yahoo.com>
Date: 2000/09/14
Raw View
"Thomas Kunert" <kunert@physik.tu-dresden.de> wrote in message
news:39C0CE36.31C08FFB@physik.tu-dresden.de...
> Anthony Williams wrote:
> >
> > I have a class template, and I want to declare a friend function that
> > performs
> > some operation on this class. The problem is, I want this friend
> > function to be
> > a template
> >
> > template<typename T>
> > class MyClass
> > {
> >   template<typename U>
> >   friend void func(MyClass<T> mc,U data);
>
> That probably does not do what you want. Here you declare a function
> template with *one* template parameter, and with two arguments. The
> first argument type is MyClass<T> and the second one is defined through
> the template parameter.

This is indeed what I want, and if I define the function inline as part of
the friend declaration, then everything works OK

>
> > };
> >
> > How can I define this function outside the class template?
> >
> > I tried:
> >
> > template<typename T>
> > template<typename U>
> > void func(MyClass<T> mc,U data)
> > {}
>
> This is ill-formed. If that has worked, your compiler is broken.

This is the syntax for a member template - see 14.5.2 of the standard. If
func had been a member function rather than a friend, then

template<typename T>
template<typename U>
void MyClass<T>::func(MyClass<T> mc,U data)
{}

should work.
>
> >
> > and
> >
> > template<typename T,typename U>
> > void func(MyClass<T> mc,U data)
> > {}
> >
>
> This declares an unrelated function template with two template
> parameters.
> What you probably want is a function template with two template
> parameters
>
> template<typename A,typename B>
> void func(MyClass<A> mc,B data)
> {}

Which is exactly my second example, but with T==A and U==B

> that is a friend of myclass<T> when A and T are the same type. That is
> not possible in c++, a friend can be either the full function template
> or some specialization of it.

It works if it is declared and defined as part of the friend declaration in
the class template, and does exactly what I expect:

template<typename T>
class MyClass
{
  template<typename U>
  friend void func(MyClass<T> mc,U data)
  {
  // function body here
  }
};

Anthony
--
alink@anthonyw.cjb.net -- Questions relating to ALINK
anthony@anthonyw.cjb.net  -- Non-ALINK questions
http://anthonyw.cjb.net/ -- ALINK home page
PGP Fingerprint:
0E2D D32A 8732 DC31 804C  D435 9BF0 F8FE 1C1B 9AD5
PGP Key at: http://i3.yimg.com/3/c7e5ee24/g/68fc2307.asc
---
[ 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              ]