It is ill-formed, and is not valid C++ although it works in MSVC. The C++03 standard says this (7.1.5.3 §2):
3.4.4 describes how name lookup proceeds for the identifier in an elaborated-type-specifier. If the identifier resolves to a class-name
or enum-name, the elaborated-type-specifier introduces it into the
decla- ration the same way a simple-type-specifier introduces its
type-name. If the identifier resolves to a typedef- name or a template
type-parameter, the elaborated-type-specifier is ill-formed. [Note:
this implies that, within a class template with a template
type-parameter T, the declaration
friend class T;
is ill-formed. ] If name lookup does not find a declaration for the
name, the elaborated-type-specifier is ill-formed unless it is of the
simple form class-key identifier in which case the identifier is
declared as described in 3.3.1.
For this same reason you can't do things like friend class std::string;
either, but you must befriend the std::basic_string
with the template parameters.
However the new C++11 spec allows a new syntax for declaring friends, which simply is (11.3 §3 of N3242):
friend <typename-specifier>;
This new syntax allows you to do what you want (I don't know if MSVC yet supports this though):
template<typename T>
class C : public T
{
friend T;
};