It is poorly formed and invalid C ++, although it works in MSVC. The C ++ 03 standard says this (7.1.5.3 ยง2):
3.4.4 describes how name lookups are performed for an identifier in a specified type specifier. If the identifier resolves to the class name or enum-name, the specified type specifier introduces it into the declare, just as the simple type specifier represents the type-name. If the identifier allows the name typedef or template type-parameter, the specified type-specifier is poorly formed. [Note: this means that in the template of the class with the template type-parameter T, declaration
friend class T;
badly formed. ] If the name search does not find an declaration for the name, the specified type specifier is poorly formed if it is not a simple class identifier for the class, in which case the identifier is as described in 3.3.1.
For the same reason, you cannot do things like friend class std::string;
but you have to make friends with std::basic_string
with the template options.
However, the new C ++ 11 specification allows you to use the new syntax to declare friends, which is simple (11.3 ยง 3 of N3242):
friend <typename-specifier>;
This new syntax allows you to do what you want (I don't know if MSVC still supports this):
template<typename T> class C : public T { friend T; };
source share