Использование друга в шаблонах - PullRequest
12 голосов
/ 12 июня 2011

Я пишу небольшой класс, класс по сути является фабрикой для класса C, но я хочу, чтобы другие классы имели доступ к некоторым методам.

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

Это должно сделать поля CFactory доступными для класса C, но компилятор считает иначе.

Я получаю следующие две ошибки при использовании gcc на Mac.

ошибка: использование параметра типа шаблона 'C' после 'class'

ошибка: объявление друга не называет класс или функцию

Может кто-нибудь сказать мне, что я делаю неправильно и как это правильно сделать?

Ответы [ 3 ]

12 голосов
/ 12 июня 2011

К сожалению, в моем понимании, это не разрешено в текущем стандарте.
§7.1.5.3 / 2 говорит:

[Примечание: ... в шаблоне класса с шаблоном типа-параметра T, декларация
друг класс Т;
плохо сформирован. Конец примечания]

В связанной заметке это ограничение, похоже, снято в C ++ 0x (§11.3 / 3 в N3290).
Кстати, MSVC может разрешить это, если мы напишем просто friend T;.

5 голосов
/ 12 июня 2011

Ответ Исе правильный - FAQ Comeau содержит вопрос, касающийся этой проблемы, более подробно.

Однако, возможно, вы можете попробовать дополнительную косвенность шаблона, которая может работать? Как то так:

template <typename T>
struct FriendMaker
{
    typedef T Type;
};

template <typename T>
class CFactory
{
public:
    friend class FriendMaker<T>::Type;
};

Однако, похоже, это работает только с gcc 4.5.x, поэтому я бы не стал на это полагаться.

3 голосов
/ 12 июня 2011

C может быть любым - int, double и т. Д., И они не являются классами.В общем, это class C не class.И вы не можете иметь что-то вроде:

class A
{
    friend class int;
    //..
};

Еще одна причина, чтобы предпочесть typename вместо class при использовании template s

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...