1

La situación es la siguiente: dispongo de una clase llamada Vector2D que utilizo para definir vectores y donde mi intención es realizar sobrecarga de operadores binarios (+,-,*) para poder operar con vectores facilmente. He realizado la sobrecarga del operador suma de la siguiente forma (adjunto definición y declaración del método dentro de la clase):

Vector2D operator +(Vector2D &v);//suma de vectores
Vector2D Vector2D::operator +(Vector2D& v)
{
Vector2D res;
res.x = x + v.x;
res.y = y + v.y;
return res;
}

Los valores x e y son atributos definidos dentro de la propia clase. El problema viene al implementar una operación de suma de vectores fuera de la clase, que me sale un error como si no se estuviese detectando la sobrecarga realizada. He hecho el correspondiente include de la clase Vector2D, pero no sé por qué el compilador parece omitir la sobrecarga.

Error   C2679   '+' binario: no se encontró un operador que adopte un operando en la parte derecha de 
tipo 'Vector2D' (o bien no existe una conversión aceptable) 

El error sale al hacer la siguiente operación:

position = position + speed * t + aceleration * (0.5f * t * t);

Aclarar que los atributos position, speed y aceleration están declarados tipo Vector2D dentro de otra clase externa a Vector2D

Muestro también como está implementado el método para la sobrecarga del operador *:

Vector2D Vector2D::operator*(float num) {
Vector2D vector;
vector.x = x * num;
vector.y = y * num;
return vector;
}

Gracias por la ayuda de antemano :)

1 Answers1

1

Tu problema es algo complicadillo de explicar ... pero muy fácil de solucionar :-)

Con un ejemplo mínimo se verá mejor:

struct Vector2D {
  Vector2D operator+( Vector2D & ) { return Vector2D( ); }
  Vector2D operator*( int ) { return Vector2D( ); }
};

int main( ) {
  Vector2D position;
  Vector2D speed;

  auto result = position + speed * 4;

  return 0;
}

Y el resultado es ...

error: cannot bind non-const lvalue reference of type ‘Vector2D&’ to an rvalue of type ‘Vector2D’
auto result = position + speed * 4;
.code.tio.cpp:2:12: note: initializing argument 1 of ‘Vector2D Vector2D::operator+(Vector2D&)’
Vector2D operator+( Vector2D & ) { return Vector2D( ); }

El kick de la cuestión es

cannot bind non-const lvalue reference ... initializing argument 1 of ‘Vector2D Vector2D::operator+

Traducido al cristiano, viene a ser que estás intentando usar un lvale en un sitio en el que se requiere un rvalue.

Para no extendernos, puedes echarle una ojeada a ¿Qué son las rvalues, lvalues, xvalues, glvalues, y prvalues?

¿ La solución ? Muy sencilla. Cambia tu operator +( ):

Vector2D operator +( const Vector2D &v);
Vector2D Vector2D::operator +( const Vector2D& v )
{
  ...

Simplemente tienes que añadirle el const.

Trauma
  • 25,297
  • 4
  • 37
  • 60
  • La función también tendría que ser const con respecto a this: `Vector2D operator +( const Vector2D &v)const` – user1754322 Apr 20 '20 at 10:57
  • Mmmmm vale, añadiendo el const se ha solucionado el problema. Pero la verdad es que no acabo de entender muy bien el error, ¿por qué está intentando acceder a un lvalue en lugar de a un rvalue? – Diego Martinez Apr 20 '20 at 11:26
  • No se si [este hilo](https://es.stackoverflow.com/q/61306/2742) te puede ser de ayuda @DiegoMartinez si no lo es, te animo a que redactes una pregunta concreta sobre ese tema. – PaperBirdMaster Apr 20 '20 at 11:28
  • Si si, el hilo me lo he leído jajajaja Pero no entiendo por qué al poner el argumento como constante se soluciona el problema – Diego Martinez Apr 20 '20 at 11:31