Por que foi introduzido std :: ranges :: less?
Em cppreferência diantestd::ranges::less , nas notas podemos ver que:
Ao contrário
std::less
,std::ranges::less
exige que todos os seis operadores de comparação<
,<=
,>
,>=
,==
e!=
de ser válida (através datotally_ordered_with
restrição).
Mas por que? Por que usaríamos em std::ranges::less{}
vez de std::less{}
? Qual é a situação prática em que queremos less{}
apenas se houver outros operadores de comparação definidos, não apenas <
aquele?
Respostas
Qual é a situação prática em que queremos menos {} apenas se houver outros operadores de comparação definidos, não apenas o <?
Nem tudo na biblioteca Ranges é baseado puramente no que é "prático". Muito disso é sobre como fazer a linguagem e a biblioteca fazerem sentido lógico.
Os conceitos como um recurso de linguagem fornecem à biblioteca padrão a oportunidade de definir combinações significativas de recursos de objeto. Dizer que um tipo tem um operator<
é útil do ponto de vista puramente prático de dizer quais operações estão disponíveis para ele. Mas isso realmente não diz nada significativo sobre o tipo.
Se um tipo for totalmente ordenado, isso logicamente significa que você pode usar qualquer um dos operadores de comparação para comparar dois objetos desse tipo. Sob a ideia de uma ordem total, a < b
e b > a
são declarações equivalentes. Portanto, faz sentido que, se o código for restrito a tipos que fornecem uma ordem total, esse código deve ter permissão para usar qualquer uma das instruções.
ranges::less::operator()
não usa nenhum operador diferente de <
. Mas essa função é restrita a tipos que modelam o totally_ordered
conceito. Essa restrição existe porque ranges::less
é para isso : comparar tipos totalmente ordenados. Poderia ter uma restrição mais estreita, mas isso seria jogar fora qualquer significado fornecido pela ordenação total.
Também evita que você exponha detalhes de implementação arbitrários aos usuários. Por exemplo, digamos que você tenha um modelo que aceita algum tipo T
e deseja usar T
em uma ranges::less
operação baseada em. Se você restringir este modelo para apenas ter um operator<
, então você efetivamente colocou sua implementação na restrição. Você não tem mais a liberdade de alternar para a implementação ranges::greater
internamente. Ao passo que, se você tivesse colocado std::totally_ordered
sua restrição, deixaria claro para o usuário o que ele precisa fazer, ao mesmo tempo em que se dá a liberdade de usar quaisquer functores de que precisar.
E como operator<=>
existe e facilita a implementação dos operadores de pedidos em uma função, não há desvantagens práticas . Bem, exceto para o código que precisa ser compilado em C ++ 17 e C ++ 20.
Essencialmente, você não deve escrever tipos que são "ordenados" apenas operator<
para começar.
Até onde posso dizer com base na proposta, a ideia é apenas simplificar o design dos objetos de função. std::less
é uma classe de modelo que requer um parâmetro de modelo e representa uma comparação homogênea. Este parâmetro do modelo pode ser omitido para o padrão, o std::less<void>
que permite comparações heterogêneas. O argumento parece ser que o caso homogêneo é desnecessário, já que é bem tratado pela abordagem heterogênea, de modo que o design pode ser consideravelmente simplificado e um modelo de classe não é necessário.
operator<
Não estou completamente certo de por que os outros operadores são necessários. Meu melhor palpite é que isso é apenas parte do que significa ter uma ordem total definida em C ++ entre dois tipos, possivelmente diferentes.