Pregunta

Estoy en el proceso de creación de una lista ligada doble, y han sobrecargado el operador = para hacer iguales en la lista otra:

template<class T>
void operator=(const list<T>& lst)
{
    clear();
    copy(lst);
    return;
}

pero me sale este error cuando intento compilar:

container_def.h(74) : error C2801: 'operator =' must be a non-static member

Además, si ayuda, la línea 74 es la última línea de la definición, con la "}".

¿Fue útil?

Solución

Exactamente lo que dice: sobrecargas de operadores deben ser funciones miembro. (Declarado dentro de la clase)

template<class T>
void list<T>::operator=(const list<T>& rhs)
{
    ...
}

Además, es probablemente una buena idea para devolver la LHS de = manera puede encadenar ella (como a = b = c) - de modo que sea list<T>& list<T>::operator=....

Otros consejos

Ponga ese operador dentro de la definición de clase. Debe ser un miembro operator= porque es especial y que no iba a ganar algo escribiéndolo como no miembros de todos modos. Un operador no miembro tiene dos importantes ventajas principales:

  • Las conversiones implícitas de la derecha y el lado izquierdo de la invocación del operador
  • No hay necesidad de saber sobre elementos internos de la clase. La función puede ser realizado como no miembros no amigo.

Para list<T>, tanto no es utilizable. Asignar a un resultado temporal de una conversión no tiene sentido, y void tendrá acceso a los componentes internos en la mayoría de los casos. Además, un <=> especial se proporciona automáticamente por C ++ si no se proporciona uno (el llamado operador de copia de asignación). Por lo que es posible sobrecargar <=> como no miembros habría introducido una complejidad adicional para parecer no hay ganancia práctico, y por lo que no está permitido.

Así que cambiar su código para que se parezca a esto (esto supone la <=> es no un operador de copia de asignación, pero la asignación de un <=> a otra cosa. Esto no es claro por su pregunta):

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

Es bastante normal que un <=> devuelve una referencia a sí mismo de nuevo. Te recomiendo que se adhieren a esta práctica. Se verá familiar para los programadores y podría causar sorpresas si volvería <=> de repente.

Si se sobrecarga un operador como una función miembro, se debe utilizar esta plantilla:

class A {
  A& operator=(const A& other) {
    if (this != &other) {
      ...
    }
    return *this;
  }
}

Hay tres cosas a tener en cuenta:

  1. Comprobar para la auto-asignación con el operador de asignación (como anteriormente);
  2. El argumento debe ser una referencia constante; y
  3. Devuelve el resultado de la operación como una referencia no const donde regresa * esto para permitir el encadenamiento de los operadores.

También puede sobrecargar un operador externo a la clase. Esto no es relevante para este ejemplo porque no se puede hacer con el operador de asignación, pero no vale de nada, porque en muchos casos es superior a funciones miembro. La forma típica es:

class A {
  friend const A& operator+(const A& a, const A& b);
  ...
}
const A& operator+(const A& a, const A& b) {
  A& ret = ...
  return ret;
}

Éste devuelve una referencia constante por lo que no puede hacer esto:

(a + b) = c

A partir de C ++ estándar, "Operadores binarios":

"Un operador binario se efectuará bien por una función miembro no estática con un parámetro o por una función no miembro con dos parámetros"

Se quiere definir esto en una clase, como miembro, o lo convierten en un método estático (en cuyo caso se debe tomar dos parámetros (tanto para el lval y la rval).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top