Страницы

Поиск по вопросам

среда, 15 мая 2019 г.

operator *: не удается сопоставить определение функции существующему объявлению

Имеются классы:
namespace gmath { template class alignas(s) Vector3 : public _Vector { public: template friend Vector3 operator*(const Matrix3& m, const Vector3& v); // здесь члены и другие объявления }
template class alignas(s) Matrix3 : public _Matrix { // здесь объявления и члены } }
И есть реализация выше объявленного метода:
template Vector3 gmath::operator*(const Matrix3& m, const Vector3& v) { // здесь код }
Пишу в Visual Studio 2017, при использовании данного оператора студия показывает, что он перегружен и находит его. Но при компиляции получаю это:
Ошибка C2244 operator *: не удается сопоставить определение функции существующему объявлению
Ошибка указывает именно на этот метод. MSDN сказал, что при использовании шаблонов следует проверить сопоставление реализации внимательно...Просмотрел, не нашёл. Куда копать?


Ответ

Код воспроизведен неаккуратно. Как вам удалось использовать тип Matrix3 до его объявления? Имя параметра шаблона нельзя переиспользовать в качестве параметра вложенного шаблона. У вас имя s переиспользуется таким некорректным образом. Во внутреннем friend-объявлении придется использовать другое имя для шаблонного параметра s
Что касается основной проблемы, то для того, чтобы определить член пространства имен gmath за пределами пространства имен gmath надо сначала объявить этот член пространства имен gmath внутри этого пространства имен. Того friend-объявления, которое вы сделали внутри класса, недостаточно. Оно лишь ссылается на "будущий" член пространства имен gmath, но не создает видимого объявления. Поэтому компилятор просто не знает, что за функцию вы пытаетесь определить за пределами пространства имен gmath
Вам в ваше пространство имен надо добавить явное объявление вашего оператора
namespace gmath { template class alignas(s) Matrix3 : public _Matrix { // ... };
template class alignas(s) Vector3 : public _Vector { template friend Vector3 operator*(const Matrix3& m, const Vector3& v); // ... };
template Vector3 operator*(const Matrix3& m, const Vector3& v); }
Также за пределами пространства имен gmath шаблон Vector3 называется gmath::Vector3. Именно так его и надо именовать в типе возвращаемого значения вашей функции при использовании "классического" синтаксиса
template gmath::Vector3 gmath::operator*(const Matrix3& m, const Vector3& v) { // ... }
К объявлениям параметров это замечание не относится.
Возникает вопрос: а с чего это вдруг вы взялись определять ваш оператор за пределами пространства имен? Почему вы просто не определили его внутри и не избежали почти всех этих ненужных сложностей?

Комментариев нет:

Отправить комментарий