Он некорректен и недопустим в C ++, хотя работает в MSVC. Стандарт C ++ 03 говорит об этом (7.1.5.3 §2):
3.4.4 описывает, как происходит поиск имени для идентификатора в подробном спецификаторе типа. Если идентификатор разрешается в имя класса
или enum-name, разработанный спецификатор типа вводит его в
объявление так же, как спецификатор простого типа вводит его
тип-имя. Если идентификатор преобразуется в typedef-имя или шаблон
Параметр типа, разработанный спецификатор типа плохо сформирован. [Заметка:
это означает, что в шаблоне класса с шаблоном
тип-параметр T, объявление
friend class T;
плохо сформирован. ] Если поиск по имени не находит объявление для
имя, разработанный спецификатор типа плохо сформирован, если он не имеет
идентификатор ключа класса простой формы, в этом случае идентификатор
заявлено как описано в 3.3.1.
По этой же причине вы не можете делать такие вещи, как friend class std::string;
, но вы должны подружить std::basic_string
с параметрами шаблона.
Однако новая спецификация C ++ 11 допускает новый синтаксис для объявления друзей, который просто (11.3 §3 из N3242):
friend <typename-specifier>;
Этот новый синтаксис позволяет вам делать то, что вы хотите (хотя я не знаю, поддерживает ли MSVC это):
template<typename T>
class C : public T
{
friend T;
};