Очень автоматический оператор генератор в C ++

С ++ имеет приятную идиому, которая позволяет писать классы, которые автоматически выполняют определенные отношения между операторами. Например, это позволяет определитьoperator== и не удосужился определитьсяoperator!= также. Это идея Boost.Operators.

Это пример:

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

Этот класс может многократно использоваться для обеспечения согласованной логики между== а также!= (и избежать ошибок)

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 !=
}

Теперь я хочу пойти на один уровень дальше и иметь класс, похожий наequally_comparable и определитьДругой функция. Например, еслиoperator== определяется затем определитьoperator!= (как выше), но и наоборот.

Первая наивная попытка работает

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);}
};

потому что только одна из двух функций должна быть определена вstruct A (илиoperator== или жеoperator!=). Однако это опасно, потому что если забыть определить любой оператор вA существует бесконечная рекурсия (и ошибка по времени выполнения). Это также выглядит хрупким.

Можно ли улучшить это и обнаружить, что хотя бы один из них определен в производном классе во время компиляции? или, вообще говоря, есть ли общий способ иметь класс, который генерирует отсутствующие операторы? (то есть шаг за пределами Boost.Operators).

Ответы на вопрос(1)

Ваш ответ на вопрос