объявить шаблон класса своим другом - PullRequest
4 голосов
/ 26 октября 2011

По некоторым причинам я хотел бы написать код, подобный этому:

template<class T>
class C : public T
{
friend class T;
};

Я думаю, что код понятен.Я хочу иметь шаблон класса, который определяет класс, производный от класса, переданного ему в качестве параметра шаблона, и чтобы сделать вещи немного сложнее, я бы хотел определить базовый класс как друга производного.Код, кажется, в порядке с компилятором MSVC, но компилятор GNU C ++ много жалуется.Что я должен сделать, чтобы иметь желаемую функциональность?

1 Ответ

6 голосов
/ 26 октября 2011

Он некорректен и недопустим в 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;
};
...