Глядя на Шаблоны C ++: Полное руководство (2-е издание) / официальный сайт (что в целом великолепно) Сегодня утром я натолкнулся на раздел, который мне не совсем понятен из (12.5.2, если у вас есть книга). Пропустив то, что кажется здесь неактуальным:
Если имя [в объявлении друга] не сопровождается угловыми скобками, есть две возможности
Если имя не определено [...]
Если имя квалифицировано (оно содержит ::
), имя должно ссылаться на ранее объявленную функцию или шаблон функции. Функция соответствия предпочтительнее шаблона соответствия функции. Однако такое заявление друга не может быть определением.
со следующим кодом
void multiply(void*);
template <typename T>
void multiply(T);
class Comrades {
// ... skipping some friends that do not effect the error message
friend void ::multiply(int); // refers to an instance of the template
// ...
};
gcc error:
error: ‘void multiply(int)’ should have been declared inside ‘::’
friend void ::multiply(int);
^
лязг ошибки:
error: out-of-line declaration of 'multiply' does not match any
declaration in the global namespace
friend void ::multiply(int);
^~~~~~~~
Я пытаюсь докопаться до сути, и я несколько раз набрал код (хотя, если у кого-то есть книга ...). Правильно ли правило, а компиляторы не правы? Код не является правильной демонстрацией правила?
Полный код включает более раннее определение функции друга:
class Comrades {
friend void multiply(int) { }
friend void ::multiply(int);
}
Какой кланг принимает и отклоняет gcc (это другой вопрос ). В любом случае это не демонстрирует правило, которое заявляет автор, это второе, ссылающееся на предыдущее в том же классе.