Gerador de operador muito automático em C ++
O C ++ possui um bom idioma que permite escrever classes que cumprem automaticamente certas relações entre operadores. Por exemplo, isso permite definiroperator==
e não se incomode com definidooperator!=
também. Essa é a idéia por trás do Boost.Operators.
Isto é um exemplo:
template<class Self> // this class is defined only once
struct equally_comparable{
friend bool operator!=(Self const& s1, Self const& s2){return !(s1==s2);}
};
Essa classe pode ser usada repetidamente para impor uma lógica consistente entre==
e!=
(e evite erros)
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 !=
}
Agora, quero ir um nível além e ter uma aula semelhante àequally_comparable
e defina ode outros função. Por exemplo, seoperator==
é definido, em seguida, definaoperator!=
(como acima), mas também vice-versa.
A primeira tentativa ingênua 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 apenas uma das duas funções precisa ser definida emstruct A
(ouoperator==
ouoperator!=
) No entanto, é perigoso porque, se esquecermos de definir um ou outro operadorA
há uma recursão infinita (e um segfault de tempo de execução). Também parece frágil.
É possível melhorar isso e detectar que pelo menos um é definido na classe derivada em tempo de compilação? ou, geralmente, existe uma maneira genérica de ter uma classe que gera os operadores ausentes? (ou seja, um passo além do Boost.Operators).