Generador de operador muy automático en C ++

C ++ tiene un lenguaje agradable que permite escribir clases que cumplen automáticamente ciertas relaciones entre operadores. Por ejemplo, esto permite definiroperator== y no molestar a definidooperator!= también. Esta es la idea detrás de Boost.Operators.

Esto es un ejemplo:

template<class Self> // this class is defined only once
struct equally_comparable{
    friend bool operator!=(Self const& s1, Self const& s2){return !(s1==s2);}
};

Esta clase se puede usar repetidamente para imponer una lógica consistente entre==&nbsp;y!=&nbsp;(y evitar errores)

struct A : equally_comparable<A>{ // 
    int value;
    A(int v) : value(v){}
    friend bool operator==(A const& a1, A const& a2){return a1.value == a2.value;}
};

int main(){

    A a1{4};
    A a2{4};
    assert(a1 == a2);
    A a3{5};
    assert(a1 != a3); // uses automatically generated operator !=
}

Ahora, quiero ir un nivel más allá y tener una clase similar aequally_comparable&nbsp;y definir elotro&nbsp;función. Por ejemplo sioperator==&nbsp;se define luego defineoperator!=&nbsp;(como arriba), pero también viceversa.

El primer intento ingenuo funciona

template<class Self>
struct equally_comparable{
    friend bool operator!=(Self const& s1, Self const& s2){return !(s1==s2);}
    friend bool operator==(Self const& s1, Self const& s2){return !(s1!=s2);}
};

porque solo una de las dos funciones debe definirse enstruct A&nbsp;(ya seaoperator==&nbsp;ooperator!=) Sin embargo, es peligroso porque si uno olvida definir cualquiera de los operadores enA&nbsp;Hay una recursión infinita (y una segfault de tiempo de ejecución). También se ve frágil.

¿Es posible mejorar esto y detectar que al menos uno está definido en la clase derivada en tiempo de compilación? o más generalmente, ¿hay una forma genérica de tener una clase que genere los operadores que faltan?&nbsp;(es decir, un paso más allá de Boost.Operators).