#cpp #шаблоны_с++
Есть класс Vector2, шаблонный. template class Vector2 { public: // ... friend Vector2 operator*(ConstAddress > l_v, ConstAddress r_val); // ... } // ... template Vector2 operator*(ConstAddress > l_v, ConstAddress r_val) { return Vector2 (l_v._x * r_val, l_v._y * r_val); } ConstAddress - это моё собственное извращение, но в целом это то же самое, что и const T&. При попытке скомпилировать выдаёт ошибку undefined reference to `operator*(Vector2 const&, float const&)'
Ответы
Ответ 1
(Тема всплывает с заметной периодичностью.) В качестве "друга" вы объявили нешаблонную функцию operator *. А определение ваше сделано для шаблона функции operator * - оно к вашему "другу" никакого отношения не имеет. Для оператора-друга вы не предоставили определения вообще, а именно его и пытается вызвать компилятор. Получается ошибка линковки. (Если вы заставите компилятор вызвать именно шаблонную версию оператора, определенную после класса, то вы наткнетесь на другую ошибку: "другом" эта версия оператора не является и доступа к внутренним полям класса не имеет.) Либо объявите шаблон функции в качестве "друга" templateclass Vector2 { ... template friend Vector2 operator *(ConstAddress > l_v, ConstAddress r_val); ... }; template Vector2 operator *(ConstAddress > l_v, ConstAddress r_val) { return Vector2 (l_v._x * r_val, l_v._y * r_val); } Либо перенесите определение вашего оператора прямо в тело класса - чтобы оно определяло правильную нешаблонную функцию. (Если я не ошибаюсь, синтаксиса для того, чтобы сделать это за пределами класса в С++ просто нет.) template class Vector2 { ... friend Vector2 operator *(ConstAddress > l_v, ConstAddress r_val) { return Vector2 (l_v._x * r_val, l_v._y * r_val); } ... }; В первом случае вы получите то, что я называю "ленивым" набором объявлений - все версии шаблонного оператора (для всех U) получат "дружбу" со всем версиями шаблонного класса (для всех T). Возможен также третий вариант - "неленивый" вариант шаблонного объявления, который несколько более громоздок, в котором "дружба" получится только между соответствующими (по шаблонному параметру) версиями шаблонного оператора и шаблонного класса. См. по ссылкам: Доступ к привату через friend Ссылка на неразрешенный внешний элемент
Комментариев нет:
Отправить комментарий