Sobreescribir el operador de la nave espacial cuando la clase padre no define el operador de la nave espacial para sí misma.
El siguiente código es tratado de manera diferente por los compiladores:
#include <compare>
struct A;
struct I {
virtual std::strong_ordering operator <=>(const A&) const {
return std::strong_ordering::equal;
}
};
struct A : I {
virtual std::strong_ordering operator <=>(const A&) const = default;
};
Ambos GCC y MSVC lo aceptan, pero Clang devuelve el siguiente error:
advertencia: el operador de comparación de tres vías especificado de forma predeterminada está implícitamente eliminado [-Wdefaulted-function-deleted]
virtual std::strong_ordering operator <=>(const A&) const = default;
^
el operador ‘operator<=>’ predeterminado está implícitamente eliminado porque no existe ninguna función de comparación de tres vías viable para la clase base ‘I’
error: la función eliminada ‘operator<=>’ no puede anular una función no eliminada
virtual std::strong_ordering operator <=>(const A&) const = default;
^
Demo: https://gcc.godbolt.org/z/WGrGTe89z
Parece que Clang es el único en lo correcto aquí, ya que I::operator <=>(const I&) const
no está definido, por lo que A::operator <=>(const A&) const
debe eliminarse implícitamente, y un método eliminado no puede anular un método no eliminado de I
. ¿Los otros compiladores también están en su derecho de aceptar el código?
davy.ai
No, los otros compiladores no son correctos al aceptar el código. Clang es correcto al devolver un error en este caso.
I::operator<=>(const I&) const
no está definido, por lo queA::operator<=>(const A&) const
debería ser eliminado implícitamente. Sin embargo, un método eliminado no puede anular un método no eliminado deI
, el cual no está definido en este caso. Por lo tanto, el código debería resultar en un error, como lo devuelve Clang.