Я хотел бы представить ответ, который на самом деле не является решением. Смысл этого не решения состоит в том, чтобы объяснить, почему решение работает (я допускаю, что этот ответ будет стоить мало без ответа, предоставленного songyuanyao.) Это может помочь прояснить вещи для будущих читателей, особенно если некоторые комментарии исчезают.
Для начала приведем упрощенную настройку, в которой я удалил некоторые посторонние вопросы (c .f. минимальный, воспроизводимый пример ):
template<class T>
class CMyMatrix{
friend void DisplayMatrix(CMyMatrix<T>);
};
template<class T>
void DisplayMatrix(CMyMatrix<T>) {
}
int main(){
CMyMatrix<int> matrix;
DisplayMatrix(matrix);
return 0;
}
Проблема в том, что friend
объявлен как (не шаблонная) функция, а определение DisplayMatrix
является шаблоном функции. Они не совпадают, поэтому для идентификатора DisplayMatrix
у компилятора остается два значения. Когда выясняется, какое значение использовать для строки DisplayMatrix(matrix);
, компилятор предпочитает не шаблон (который объявлен, но никогда не определен).
Таким образом, ответ заключается в том, чтобы согласовать ваше объявление и определение. Один из способов сделать это - скорее всего, не решение, которое кто-то ищет, а способ порадовать компилятор - это изменить определение, чтобы оно больше не было шаблоном.
void DisplayMatrix(CMyMatrix<int>) {
}
С этим изменением код компилируется. Ну, это соответствует требованиям, если вы используете int
в качестве параметра шаблона. Так что на самом деле не решение, а демонстрация того, что декларация friend
фактически объявляет. Реальное решение состоит в том, чтобы сохранить (шаблонное) определение DisplayMatrix
и настроить объявление friend
, как в принятом ответе.
Может быть интересно отметить, что g cc ( но явно не лязг?) есть предупреждение, применимое к этой ситуации.
warning: friend declaration 'void DisplayMatrix(CMyMatrix<T>)' declares a
non-template function [-Wnon-template-friend]
friend void DisplayMatrix(CMyMatrix<T> matrix);
^
note: (if this is not what you intended, make sure the function template
has already been declared and add <> after the function name here)