Problem with declaring a template friend.

J

James Aguilar

Hello, all.

I saw this in the provided code of a lab that I have due in a couple of
weeks in my algorithms class. It compiled fine in g++ but did not compile
with the VC++ compiler. It does not recognize the angle brackets that
follow "<<" in the operator friend declaration.

--- CODE ---

template <class T> class PriorityQueue {
....
friend std::eek:stream &operator<< <> (std::eek:stream &, PriorityQueue &);
}

template <class T>
std::eek:stream &operator<<(std::eek:stream &os, PriorityQueue<T> &q)
{
os << "not implemented yet\n";
return os;
}

--- END CODE ---

Is this code standard? If so, how do you suggest I get around the weakness
in the VC++ compiler? If not, how should I write this?

Sincerely,

James
 
J

James Aguilar

A quick note: requesting help on syntax and language semantics is not
forbidden in my class, so worry not about whether or not it would be
cheating to help me.
 
R

Rob Williscroft

James Aguilar wrote in in
comp.lang.c++:
Hello, all.

I saw this in the provided code of a lab that I have due in a couple
of weeks in my algorithms class. It compiled fine in g++ but did not
compile with the VC++ compiler. It does not recognize the angle
brackets that follow "<<" in the operator friend declaration.

Add the following declarations before you class:

template <class T> class PriorityQueue; /* needed next ... */

template <class T>
--- CODE ---

template <class T> class PriorityQueue {
...
friend std::eek:stream &operator<< <> (std::eek:stream &, PriorityQueue &);
}

template <class T>
std::eek:stream &operator<<(std::eek:stream &os, PriorityQueue<T> &q)
{
os << "not implemented yet\n";
return os;
}

--- END CODE ---

Is this code standard?

No, add the declaration before the class, the compiler needs to
know that operator << is template before the friend declaration.
If so, how do you suggest I get around the
weakness in the VC++ compiler? If not, how should I write this?

The VC compiler is Standard conforming in this regard and latter
versions of g++ (3.4 and 4.0) are too.

HTH.

Rob.
 
J

James Aguilar

Rob Williscroft said:
The VC compiler is Standard conforming in this regard and latter
versions of g++ (3.4 and 4.0) are too.

So if I had g++ 3.3.3 for Cygwin, that might have been why it would compile
without those two declarations? Excellent, and thank you for the help. It
works now on the MS compiler.

I also found that if I do

friend std::eek:stream &operator<< <T>(std::eek:stream &, PriorityQueue<T> &);

instead of

friend std::eek:stream &operator<< <>(std::eek:stream &, PriorityQueue<T> &);

it still works. Is there a real difference? Why do I need those empty
brackets in the first place? (I understand the general idea and most of the
semantics of templates, but some of the less commonly encountered points
still escape me.)

Once again, thanks for the help!

James
 
S

Surendra Singhi

James said:
So if I had g++ 3.3.3 for Cygwin, that might have been why it would compile
without those two declarations? Excellent, and thank you for the help. It
works now on the MS compiler.

I also found that if I do

friend std::eek:stream &operator<< <T>(std::eek:stream &, PriorityQueue<T> &);

instead of

friend std::eek:stream &operator<< <>(std::eek:stream &, PriorityQueue<T> &);

it still works. Is there a real difference? Why do I need those empty
brackets in the first place? (I understand the general idea and most of the
semantics of templates, but some of the less commonly encountered points
still escape me.)

Once again, thanks for the help!

James
I think it is parsing problem. A reason why C++ and templates are
syntactic nightmares!!!
The compiler is confused whether you meant < << > or << <> .

Hang on there must be few C++ experts around who will clarify it.

Even I was confused when I first saw the code wondering whether you wanted.
 
R

Rob Williscroft

James Aguilar wrote in in
comp.lang.c++:
So if I had g++ 3.3.3 for Cygwin, that might have been why it would
compile without those two declarations? Excellent, and thank you for
the help. It works now on the MS compiler.

I also found that if I do

friend std::eek:stream &operator<< <T>(std::eek:stream &, PriorityQueue<T>
&);

This had me confused for a while, I thought you meant that, the above
works without the forward declarations, but it doesn't (MSVC 7.1).
instead of

friend std::eek:stream &operator<< <>(std::eek:stream &, PriorityQueue<T>
&);

it still works. Is there a real difference?

Not really, the first (<T>) form is just more explicit than the second.

In the second form the compiler deduces the T for you from the forward
declaration and the paramiter types you give in the friend declaration.

Why do I need those
empty brackets in the first place? (I understand the general idea and
most of the semantics of templates, but some of the less commonly
encountered points still escape me.)

The empty brackets tell the compiler that you are befriending a
template function, without them, it will make your class a friend of
the non-template:

std::eek:stream &operator << ( std::eek:stream &, PriorityQueue< T > & );

This declaration *doesn't* refer to a specialization of the template
function:

template < typename T >
std::eek:stream &operator << ( std::eek:stream &, PriorityQueue< T > & );

You would have to provide an (overloaded) defenition for each type:

std::eek:stream &operator << ( std::eek:stream &, PriorityQueue< int > & )
{
return os << "int overload";
}

Rob.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top