views:

162

answers:

2

When researching an answer to a question (based on this answer) I tried to do the following:

template <class T>
class friendly {
    friend class T;
};

friendly<string> howdy;

This fails to compile with the following error:

error: template parameter "T" may not be used in an elaborated type specifier friend class T;

From what I can understand from my good friend Google this is so that I won't accidentally try to instantiate friendly<int> but why should this be an error when compiling the template? Should't it be an error when instantiating the template with an invalid type (such as had I written int f() { return T::foo(); })

+1  A: 

Section 7.1.5.3 of the standard explicitly describes this as an example of an illformed elaborated type specifier.

A discussion about the subject can be found here.

Dave Van den Eynde
+1, good find. I remember butting up against this one time. I don't know why it's verboten though -- maybe it caused difficulties for compiler implementors?
j_random_hacker
Don't question the bible, son.
Dave Van den Eynde
I had a look at the referenced thread and apart from pointing out that it's illegal there is no insight as to why (which is what I'm after in this question).
Motti
You're right. I don't know what the rationale is either. But that goes for a lot of things in a language designed by committee.
Dave Van den Eynde
A: 

A bit more googleling brought up Extended friend Declarations (PDF) for C++0x.

This document contains the following:

template <typename T> class R {
    friend T;
};
R<C> rc; // class C is a friend of R<C>
R<int> ri; // OK: “friend int;” is ignored

Which goes even further than what I thought (ignoring illegal friend decelerations rather than failing during instantiation). So I guess the answer is that there isn't a good reason and it's being rectified.

Motti