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

Problem with declaring a template friend.

P: n/a
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::ostream &operator<< <> (std::ostream &, PriorityQueue &);
}

template <class T>
std::ostream &operator<<(std::ostream &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
Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
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.
Jul 22 '05 #2

P: n/a
James Aguilar wrote in news:co**********@newsreader.wustl.edu 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>
std::ostream &operator<<(std::ostream &os, PriorityQueue<T> &q);

--- CODE ---

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

template <class T>
std::ostream &operator<<(std::ostream &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.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #3

P: n/a
"Rob Williscroft" <rt*@freenet.co.uk> wrote in message
news:Xn**********************************@130.133. 1.4...
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::ostream &operator<< <T>(std::ostream &, PriorityQueue<T> &);

instead of

friend std::ostream &operator<< <>(std::ostream &, 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
Jul 22 '05 #4

P: n/a
James Aguilar wrote:
"Rob Williscroft" <rt*@freenet.co.uk> wrote in message
news:Xn**********************************@130.133. 1.4...
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::ostream &operator<< <T>(std::ostream &, PriorityQueue<T> &);

instead of

friend std::ostream &operator<< <>(std::ostream &, 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.
--
Surendra Singhi

www.public.asu.edu/~sksinghi
Jul 22 '05 #5

P: n/a
James Aguilar wrote in news:co**********@newsreader.wustl.edu in
comp.lang.c++:
"Rob Williscroft" <rt*@freenet.co.uk> wrote in message
news:Xn**********************************@130.133. 1.4...
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::ostream &operator<< <T>(std::ostream &, 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::ostream &operator<< <>(std::ostream &, 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::ostream &operator << ( std::ostream &, PriorityQueue< T > & );

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

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

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

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

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.