C++ 3d.Комментарии

       

. Друзья


Приведенный в конце страницы пример нужно заменить на: template<class C> class Basic_ops { // базовые операции с контейнерами friend bool operator==<>(const C&, const C&); // сравнение элементов friend bool operator!=<>(const C&, const C&); // ... };

Уголки (<>) после имен функций означают, что друзьями являются функции-шаблоны (поздние изменения стандарта).

Этот текст взят из списка авторских исправлений к 10 тиражу.

Почему в данном случае необходимы <>? Потому что иначе мы объявляем другом operator==() не шаблон, т.к. до объявления класса в окружающем контексте не было объявления operator==()-шаблона. Вот формулировка стандарта:

14.5.3. Друзья [temp.friend]

Другом класса или класса-шаблона может быть функция-шаблон, класс-шаблон, их специализации или обычная (не шаблон) функция или класс. Для объявления функций-друзей которые не являются объявлениями шаблонов:

    если имя друга является квалифицированным или неквалифицированным template-id, то объявление друга ссылается на специализацию функции-шаблона, иначе

    если имя друга является qualified-id и в указанном классе или пространстве имен найдена соответствующая функция не шаблон, то объявление друга ссылается на эту функцию, иначе

    если имя друга является qualified-id и в указанном классе или пространстве имен найдена соответствующая специализация функции-шаблона, то объявление друга ссылается на эту функцию, иначе

    имя должно быть unqualified-id, который объявляет (или переобъявляет) обычную (не шаблон) функцию.

    Например: template<class T> class task; template<class T> task<T>* preempt(task<T>*);

    template<class T> class task { // ... friend void next_time(); friend void process(task<T>*); friend task<T>* preempt<T>(task<T>*); template<class C> friend int func(C);

    friend class task<int>; template<class P> friend class frd; // ... };

    здесь функция next_time является другом каждой специализации класса-шаблона task; т.к. process не имеет явных template-arguments, каждая специализация класса-шаблона task имеет функцию-друга process соответствующего типа и этот друг не является специализацией функции-шаблона; т.к. друг preempt имеет явный template-argument <T>, каждая специализация класса-шаблона task имеет другом соответствующую специализацию функции-шаблона preempt; и, наконец, каждая специализация класса-шаблона task имеет другом все специализации функции-шаблона func. Аналогично, каждая специализация класса-шаблона task имеет другом класс-специализацию task<int>, и все специализации класса-шаблона frd.



    Содержание раздела