By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,137 Members | 1,311 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,137 IT Pros & Developers. It's quick & easy.

friend operator<< in template classes

P: n/a
What is the difference between

friend ostream & operator<<(ostream & OUT, const Foo & f){
// output f
return OUT;
}

and

template <class X>
friend ostream & operator<<(ostream & OUT, const Foo<X> & f){
// output f
return OUT;
}

either one defined INSIDE a

template <class T>
class Foo
{
//
};

They both work, but is there a difference? The latter is a
template function inside a template class, right? I understand that part.
But why doesn't the former need template<class X> and Foo<X>& ?

I use these on a daily basis, and suddenly I felt the urge for
clarification. Thanks!

Jan 22 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a

"Amadeus W. M." <am*******@cablespeed.com> skrev i meddelandet
news:pa****************************@cablespeed.com ...
What is the difference between

friend ostream & operator<<(ostream & OUT, const Foo & f){
// output f
return OUT;
}

and

template <class X>
friend ostream & operator<<(ostream & OUT, const Foo<X> & f){
// output f
return OUT;
}

either one defined INSIDE a

template <class T>
class Foo
{
//
};

They both work, but is there a difference? The latter is a
template function inside a template class, right? I understand that
part.
But why doesn't the former need template<class X> and Foo<X>& ?


The difference is, like you say, that the first version defines a
single friend operator. The second one defines a whole group of
friends, one for each possible X. In this particual case, that doesn't
seem neccessary.


Bo Persson
Jan 22 '06 #2

P: n/a
"Bo Persson" <bo*@gmb.dk> wrote in message
news:43*************@individual.net
"Amadeus W. M." <am*******@cablespeed.com> skrev i meddelandet
news:pa****************************@cablespeed.com ...
What is the difference between

friend ostream & operator<<(ostream & OUT, const Foo & f){
// output f
return OUT;
}

and

template <class X>
friend ostream & operator<<(ostream & OUT, const Foo<X> & f){
// output f
return OUT;
}

either one defined INSIDE a

template <class T>
class Foo
{
//
};

They both work, but is there a difference? The latter is a
template function inside a template class, right? I understand that
part.
But why doesn't the former need template<class X> and Foo<X>& ?


The difference is, like you say, that the first version defines a
single friend operator. The second one defines a whole group of
friends, one for each possible X. In this particual case, that doesn't
seem neccessary.


That is not the difference. When defined inside the class definition, the
first version is also a template operator. Consider:

#include <iostream>
using namespace std;
template <class T>
class Foo
{
T x;
public:
Foo(const T& arg) : x(arg)
{}
friend ostream & operator<< (ostream & out, const Foo & f)
{
out << f.x;
return out;
}
};

int main()
{
Foo<int> f(5);
cout << f << endl;

Foo<string> g("Text");
cout << g << endl;

return 0;
}

Apparently it makes all the difference whether the friend operator is
defined inside or outside the class. In the former case, the template form
is implicit, just as it is in, say, the definition of the Foo constructor or
any other member function.
--
John Carson
Jan 22 '06 #3

P: n/a

"John Carson" <jc****************@netspace.net.au> skrev i meddelandet
news:43**********************@un-2park-reader-01.sydney.pipenetworks.com.au...
"Bo Persson" <bo*@gmb.dk> wrote in message
news:43*************@individual.net
"Amadeus W. M." <am*******@cablespeed.com> skrev i meddelandet
news:pa****************************@cablespeed.com ...
What is the difference between

friend ostream & operator<<(ostream & OUT, const Foo & f){
// output f
return OUT;
}

and

template <class X>
friend ostream & operator<<(ostream & OUT, const Foo<X> & f){
// output f
return OUT;
}

either one defined INSIDE a

template <class T>
class Foo
{
//
};

They both work, but is there a difference? The latter is a
template function inside a template class, right? I understand
that
part.
But why doesn't the former need template<class X> and Foo<X>& ?


The difference is, like you say, that the first version defines a
single friend operator. The second one defines a whole group of
friends, one for each possible X. In this particual case, that
doesn't
seem neccessary.


That is not the difference. When defined inside the class
definition, the first version is also a template operator.


Yes, it's templated on T, as Foo means Foo<T> in this context. But
there is only one friend operator<< for each specific instantiation of
Foo.

The template<class X> version makes each operator<< a friend of all
Foo's. This means that that

template<>
ostream& operator(ostream&, const Foo<A>&)

will have access to the internals of Foo<B>, Foo<C>, etc. The
non-template version will not.
Bo Persson
Jan 22 '06 #4

P: n/a
On Sun, 22 Jan 2006 14:51:49 +0100, Bo Persson wrote:

"John Carson" <jc****************@netspace.net.au> skrev i meddelandet
news:43**********************@un-2park-reader-01.sydney.pipenetworks.com.au...
"Bo Persson" <bo*@gmb.dk> wrote in message
news:43*************@individual.net
"Amadeus W. M." <am*******@cablespeed.com> skrev i meddelandet
news:pa****************************@cablespeed.com ...
What is the difference between

friend ostream & operator<<(ostream & OUT, const Foo & f){
// output f
return OUT;
}

and

template <class X>
friend ostream & operator<<(ostream & OUT, const Foo<X> & f){
// output f
return OUT;
}

either one defined INSIDE a

template <class T>
class Foo
{
//
};

They both work, but is there a difference? The latter is a
template function inside a template class, right? I understand
that
part.
But why doesn't the former need template<class X> and Foo<X>& ?

The difference is, like you say, that the first version defines a
single friend operator. The second one defines a whole group of
friends, one for each possible X. In this particual case, that
doesn't
seem neccessary.


That is not the difference. When defined inside the class
definition, the first version is also a template operator.


Yes, it's templated on T, as Foo means Foo<T> in this context. But
there is only one friend operator<< for each specific instantiation of
Foo.

The template<class X> version makes each operator<< a friend of all
Foo's. This means that that

template<>
ostream& operator(ostream&, const Foo<A>&)

will have access to the internals of Foo<B>, Foo<C>, etc. The
non-template version will not.
Bo Persson


So, in the "non-templated" version, if I have

Foo<A> a; // A's version of operator<< is instantiated here, with Foo<A>
Foo<B> b; // b's version of operator<< is instantiated.

cout << a; // operator<<(ostream &, const Foo<A> &) is called.
cout << b; // operator<<(ostream &, const Foo<B> &) is called.

The two versions of operator<<() are different, but from the user's
standpoint, it doesn't matter that the Foo<B> version of operator<<
does not have access to Foo<A>'s internals. The instantiation of
operator<<() for each type A and B occurs whether or not we call
them.
On the other hand, in the templated case, operator<<() is not
actually instantiated UNLESS we call cout << a; cout << b;

Again, it is irrelevant to the user whether or not A's version of
operator<< has access to B's internals.

Is this the point?

Jan 22 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.