matrices - sobrecarga de operadores relacionales en c++
En C++, ¿necesita sobrecargar el operador== en ambas direcciones? (2)
Si tu puedes. Al igual que en muchos otros idiomas, C ++ toma partido y las comparaciones entre dos objetos de diferentes tipos llevarán a dos operadores de comparación diferentes según el orden.
Por supuesto, desea que sean coherentes y no sorprendentes, por lo que el segundo debe definirse en términos del primero.
Digamos que estoy trabajando con una clase:
class Foo{
public:
std:string name;
/*...*/
}/*end Foo*/
y proporciono una sobrecarga para el
operator==
bool operator==(const Foo& fooObj, const std::string& strObj) {
return (fooObj.name == strObj);
}
¿También necesito volver a implementar la misma lógica a la inversa?
bool operator==(const std::string& strObj, const Foo& fooObj) {
return (strObj == fooObj.name);
}
(C ++ 20 en adelante)
Con la aceptación de p1185 en C ++ 20, no necesita proporcionar más de una sobrecarga. El periódico realizó estos cambios (entre otros) a la norma:
[over.match.oper]
eel.is/c++draft/over.match.oper#3.4 - [...] Para el operador
!=
([Expr.eq]), los candidatos reescritos incluyen a todos los miembros, no miembros y candidatos incorporados para el operador==
para el cual la expresión reescrita(x == y)
está bien formado cuando se convierte contextualmente a bool usando ese operador==
. Para los operadores de igualdad, los candidatos reescritos también incluyen un candidato sintetizado, con el orden de los dos parámetros invertidos, para cada miembro, no miembro y candidato incorporado para el operador==
para el cual la expresión reescrita(y == x)
está bien formado cuando se convierte contextualmente a bool usando ese operador==
. [Nota: un candidato sintetizado a partir de un candidato miembro tiene su parámetro objeto implícito como segundo parámetro, por lo que las conversiones implícitas se consideran para el primer parámetro, pero no para el segundo. - nota final] [...]8 [...] Si se selecciona un candidato reescrito por resolución de sobrecarga para un operador
!=
,x != y
se interpreta como(y == x) ? false : true
(y == x) ? false : true
si el candidato seleccionado es un candidato sintetizado con orden inverso de parámetros, o(x == y) ? false : true
(x == y) ? false : true
contrario, utilizando eloperator==
reescrito seleccionadooperator==
candidato. Si se selecciona un candidato reescrito por resolución de sobrecarga para un operador==
,x == y
se interpreta como(y == x) ? true : false
(y == x) ? true : false
usando eloperator==
reescrito seleccionadooperator==
candidato.
Lo anterior significa que no solo
no
necesita proporcionar al operador el orden de los operandos invertidos,
sino
que también obtiene
!=
Gratis!
Además, la función
operator==
puede ser un miembro si tiene sentido.
Aunque como lo indica la nota en el primer párrafo anterior, ser miembro o una función gratuita afectará las conversiones implícitas, por lo que aún debe tener eso en cuenta.
(Hasta C ++ 17)
Hazlo si quieres admitir comparaciones donde la cadena está a la izquierda y
Foo
está a la derecha.
Una implementación no reordena los argumentos a un
operator==
sobrecargado
operator==
para que funcione.
Pero puedes evitar repetir la lógica de la implementación, sin embargo. Asumiendo que su operador debe comportarse como se espera:
inline bool operator==(const std::string& objA, const Foo& objB) {
return objB == objA; // Reuse previously defined operator
}