O operador de comparação de três vias é sempre eficiente?
Herb Sutter, em seuproposta para o operador "nave espacial" (seção 2.2.2, parte inferior da página 12), diz:
Baseando tudo em<=>
e seu tipo de retorno: Este modelo possui grandes vantagens, algumas exclusivas desta proposta, em comparação com as propostas anteriores para C ++ e os recursos de outras linguagens:
[...]
(6)Eficiência, incluindo finalmente a obtenção de abstração zero zero para comparações: A grande maioria das comparações é sempre de passagem única. A única exceção é gerada<=
e>=
no caso de tipos que suportam a ordem parcial e a igualdade. Para<
, o passe único é essencial para alcançar o princípio de zero sobrecarga para evitar repetições de comparações de igualdade, como parastruct Employee { string name; /*more members*/ };
usado emstruct Outer { Employeee; /*more members*/ };
- as comparações de hoje violam a abstração de sobrecarga zero porqueoperator<
emOuter
realiza comparações redundantes de igualdade, porque executaif (e != that.e) return e < that.e;
que atravessa o prefixo igual dee.name
duas vezes (e se o nome for igual, percorre os prefixos iguais de outros membros deEmployee
duas vezes mais), e isso não pode ser otimizado em geral. Como observa Kamiński, a abstração com sobrecarga zero é um pilar do C ++, e alcançá-lo para comparações pela primeira vez é uma vantagem significativa desse design com base em<=>
.
Mas então ele dá este exemplo (seção 1.4.5, página 6):
class PersonInFamilyTree { // ...
public:
std::partial_ordering operator<=>(const PersonInFamilyTree& that) const {
if (this->is_the_same_person_as ( that)) return partial_ordering::equivalent;
if (this->is_transitive_child_of( that)) return partial_ordering::less;
if (that. is_transitive_child_of(*this)) return partial_ordering::greater;
return partial_ordering::unordered;
}
// ... other functions, but no other comparisons ...
};
Definiriaoperator>(a,b)
Comoa<=>b > 0
não levar a grandes despesas gerais? (embora de uma forma diferente da que ele discute). Esse código testaria primeiro a igualdade, depois aless
e finalmente paragreater
, em vez de testar apenas e diretamentegreater
.
Estou faltando alguma coisa aqui?