0

I have ambiguously overloaded the member function operator- of my vector (mathematics) class.

Can I resolve this issue? At the moment I am a bit stuck as to how to proceed.

Code:

class vector
{
  double mx, my;

  // Constructor not written for clarity

  vector operator-() const;
  friend vector operator-(vector &lhs, vector &rhs);

}

vector vector::operator-() const
{
  return vector(-mx, -my);
}

vector operator-(vector &lhs, vector &rhs) const // Note const here!
{
  return vector(lhs.mx - lhs.my, rhs.mx - rhs.my);
}

In case you need to know what the constructor is, it's just the expected:

vector::vector(double x, double y)
{
  mx = x; my = y;
}

The line of code where the problem flags up is:

vector a(0.0, 0.0);
vector b(0.0, 0.0);
vector c = a - b;

That should be about enough info to describe the problem in detail. There is also a default copy operator=.

The problem is of course that the compiler doesn't know if I want to subtract these vectors or negate one and then get a compiler error due to vector c = vector vector or vector c = a b if you like, which is nonsense code.

EDIT: I missed a vitally important piece of information, which I now realize explains the problem:

The problematic lines of code appear in a function where the arguments are passed as const references.

void function(const vector &a, const vector &b)
{
  vector a(0.0, 0.0);
  vector b(0.0, 0.0);
  vector c = a - b;
}

That isn't specifically a problem, however the function I wrote above should have actually been for operator-=. The operator- (subtraction) is then defined in terms of operator-=. So to explain fully, this is the problem:

vector& vector::operator-=(const Vector3& rhs)
{
  m_x -= rhs.m_x;
  m_y -= rhs.m_y;
  return *this;
}

vector operator-(vector &lhs, vector &rhs)
{
  lhs -= rhs;
  return lhs;
}

Which explains the problem - the function operator- (negation) promises not to modify the members by the use of const, and the 2 other operators for subtraction are defined in terms of each other. I think the solution is to do the following:

vector operator-(vector &lhs, const vector &rhs)
{
  vector v = lhs;
  v -= rhs;
  return lhs;
}

Or if not that then perhaps the more verbose method:

vector operator-(const vector &lhs, const vector &rhs)
{
  vector v = vector(lhs.mx - lhs.my, rhs.mx - rhs.my);
  return v;
}

I'll test this now - I've got a bit of a headache at the moment so I guess I must not be thinking 100 % clearly.

Edit: Got it working now, just had to modify the subtraction operator to be a friend function.

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225

1 Answers1

3

You should define the operator- as

vector operator-(const vector &lhs, const vector &rhs)
{
    return vector(lhs.mx - lhs.my, rhs.mx - rhs.my);
}

The compiler tries to use the unary operator- because it applies on a const vector.

When you write vector c = a - b; and a and b are const vectors, the compiler looks for the above function which it doesn't find. It only finds an operator with none constant arguments. Since you don't modify the arguments, define them as const.

The const keyword you added after it is not valid. It should only appear with methods and specifies that the object is not modified by the method. The compiler should complain about its presence with a function definition.

chmike
  • 20,922
  • 21
  • 83
  • 106