Очень автоматический оператор генератор в 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).