friend operator<< in template classes

A

Amadeus W. M.

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!
 
B

Bo Persson

Amadeus W. M. said:
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
 
J

John Carson

Bo Persson said:
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.
 
B

Bo Persson

John Carson said:
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
 
A

Amadeus W. M.

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?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,044
Latest member
RonaldNen

Latest Threads

Top