Re: friend of template class
From: Jarek (jaroosh_at_poczta.wp.pl)
Date: 07/12/04
- Previous message: Robert W Hand: "Re: Which Language ??"
- In reply to: Gwar: "friend of template class"
- Next in thread: Jarek: "Re: friend of template class"
- Reply: Jarek: "Re: friend of template class"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 12 Jul 2004 02:43:07 +0200
Uzytkownik "Gwar" <xeno@xor.qua> napisal w wiadomosci
news:20040711150048.Q38088@synergy.transbay.net...
>
>
>
> I got this to compile & to do what it's suppose to do but I need to
> know why I must declare the friend function inside the class A thus:
>
> template <class T> class A;
> template <class T> ostream & operator<<(ostream &os, const A<T> &a);
> template <class T>
> class A
> {
> ...
> // the question is about the <> after the function name
> friend ostream & operator << <T> (operator & os, const A<T> &a);
> };
>
> // It wasn't necessary to do this when defining it
> template <class T> ostream & ostream << (ostream &os, const A<T> &a)
> {
> os << a.data_ << endl;
> return os;
> }
This is a complex issue.
In brief - putting <T> or just <> just before the brackets in :
friend ostream & operator << <T> (operator & os, const A<T> &a);
tells the compiler that this operator is a template (if <>/<T> were ommited,
compiler would be seeking
non-template definition of operator << (operator & os, const A<T> &a); in
the global scope where the
class A is defined, and obviously, it would fail since there is no such
(non-template) definition).
You also should (C++ standard requirement I think, though my devc++ compiler
doesn't actually enforce that) declare the template friend function, this is
why there are actually two declarations of operator << <T> (operator & os,
const A<T> &a)
a) one outside the scope of the class definition since the operator is
not it's member (and because class A is the operator's argument, the class
has to be declared also)
b) second - inside the class definition, just to say that it is it's
friend
What actually happens here, is that when you instantiate the template class,
providing a T - for example with float, (with it's first use)
a new operator
friend ostream & operator << <float> (operator & os, const A<T> &a);
is created and though there might be different instantiations of class A,
A<int>, A<long>, A<someClass> in the program (and thus,
as many operator<< instatiations), ONLY this <float> operator is a friend of
<float> class.
Since this operator is a TEMPLATE, and it is not a member of class A, we
can't give compiler a hint where to look for it's definition for the
particular
class instantiation, in form of a class quialifier as in case of member
functions, so we must put <> or <T> to indicate that this operator is bound
to
a particular class template.
This is only necessary when you define the operator OUTSIDE the class
definition, since if you provide the friend operator's body with the
declaration,
compiler doesn't need to look for the operator's definition during the
linking.
The code could be then rewritten as follows :
template <class T>
class A
{
...
friend ostream & operator <<(operator & os, const A<T> &a)
{
os << a.data_ << endl;
return os;
}
};
Here, operator << is NOT a template anymore
By instantiating A to A<int>, A<float> etc. we just get overloaded operators
like
operator<<(operator & os, const A<int> &a)
operator<<(operator & os, const A<float> &a)
Anyways, putting <>/<T> before the brackets in the operator declaration is a
C++ standard requirement,
it helps the compiler link the operator's declaration (which by the time of
class instantiation might take the form , eg : operator<<(const A<int>&))
with it's definition (that is yet still a template - if the <>/<T> were
omited, compiler would assume that operator<<(const A<int>&)) is a
declaration
of an ordinary (nontemplate) function, and seek for the EXACT
operator<<(const A<int>&)) match, but there is no such, since we only have
template definition for operator<<(const A<T>&)) that is somewhere outside
the class' definition.
This is not necessary with the friend operator defined in the class
definition, since by the time of substituting T for some type/class,
compiler gets both :
exact instantiated definition AND it's body.
---------
Cheers
J.W.
- Previous message: Robert W Hand: "Re: Which Language ??"
- In reply to: Gwar: "friend of template class"
- Next in thread: Jarek: "Re: friend of template class"
- Reply: Jarek: "Re: friend of template class"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|