Я работаю над классом Vector2D, и я думаю, что и векторное, и скалярное сложение имеет смысл реализовывать с помощью операторов + = / +.
Проблема в том, что я на самом деле не знаю, как обойти эту кажущуюся двусмысленность аргументов, вот что говорит Кланг:
vector2d_test.cpp:17:16: error: use of overloaded operator
'+=' is ambiguous (with operand types 'Vector2D<float>' and 'int')
vector += 1;
~~~~~~ ^ ~~~~~~~
vector2d.hpp:34:18: note: candidate function
Vector2D<T>& operator+=(const Vector2D<T>& other)
^
vector2d.hpp:41:18: note: candidate function
Vector2D<T>& operator+=(const T summand) const
Вот две функции:
Vector2D<T>& operator+=(const Vector2D<T>& other)
{
x += other.x;
y += other.y;
return *this;
}
template <typename S>
Vector2D<T>& operator+=(const S summand) const
{
x += summand;
y += summand;
return *this;
}
Итак … есть идеи, что я могу с этим поделать?
Непонятно, что ты пытаешься сделать. operator+=
функции, которые вы публикуете, не являются законными, если они не являются членами. И если
они являются членами, и у вас есть что-то вроде:
Vector2D<float> v;
// ...
v += 1;
Vector2D<float>::operator+=( Vector2D<float> const& )
функция не вызывается, и поэтому не может быть никакой двусмысленности. Если
функции не являются членами, тогда они должны быть написаны:
template <typename T>
Vector2D<T>& operator+=( Vector2D<T>& lhs, Vector2D<T> const& rhs );
template <typename T, typename U>
Vector2D<T>& operator+=( Vector2D<T>& lhs, U rhs );
Даже в этом случае первый не может быть вызван с rhs
из
тип int
, поэтому нет никакой двусмысленности.
РЕДАКТИРОВАТЬ:
Я пропустил const
в конце второго в вашем сообщении.
Это очевидная опечатка с вашей стороны, она по-прежнему не меняется
что-нибудь, если у вас также есть некоторые неявные преобразования в
Vector2D
(что, вероятно, не очень хорошая идея); в противном случае
Первая версия до сих пор не вызывается. Если есть, например,
неявное преобразование из int
в Vector2D
и ты звонишь
+=
на неконстантном Vector2D первая перегрузка
лучшее соответствие для неявного первого аргумента (что приводит к
this
указатель), так как это точное совпадение, даже без
преобразование в CV, но вторая функция лучше подходит для
второй аргумент, потому что результаты создания шаблона
в точном соответствии. Так что вызов неоднозначен.
Вы все написали в вас сообщение об ошибке. Вы пытались добавить в векторную переменную типа int, но в вашем векторе есть числа с плавающей точкой. Так должно быть:
vector += 1f;
или же
vector += 1.0;
Взглянуть. Когда у вас есть этот вектор:
Vector2D<float> vector;
функция, соответствующая этому вектору, имеет заголовок:
Vector2D<T>& operator+=(const float summand) const;
Второй не имеет значения прямо сейчас. И когда вы пытаетесь добавить к своему вектору 1, вы пытаетесь вызвать функцию:
Vector2D<T>& operator+=(const int summand) const;
Который вы не заявили. Вот почему компилятор сообщает вам об ошибке — он не может найти правильную функцию.
Самый простой способ — определить функции внутри Vector2D ala:
Vector2D& operator+=(const Vector2D& rhs)
{ ...each this element += rhs's corresponding element... }
Vector2D& operator+=(const T& summand)
{ ...each this elements += summand... }
friend Vector2D operator+(Vector2D lhs, const Vector2D& rhs) { return lhs += rhs; }
friend Vector2D operator+(Vector2D lhs, const T& rhs) { return lhs += rhs; }
Заметки:
friend
s, что позволяет их удобно определять inlineconst
(один был в вашем вопросе)T
является float
затем int
с будет отлично работать, если вы не сделаете что-то смешное, например, дать Vector2D
неявный конструктор из одного int
что делает выбор конверсии неоднозначным