Enquanto eu estava tentando aprender sobre C ++ operadores, me deparei com um operador de comparação estranha em cppreference.com , * em uma tabela que ficou assim:
"Bem, se esses são operadores comuns em C ++, é melhor eu aprendê-los", pensei. Mas todas as minhas tentativas de elucidar esse mistério foram infrutíferas. Mesmo aqui, no Stack Overflow, não tive sorte na minha pesquisa.
Existe uma conexão entre <=> e C ++ ?
E, se houver, o que esse operador faz exatamente?
* Enquanto isso, o cppreference.com atualizou essa página e agora contém informações sobre o <=>
operador.
bar< foo::operator<=>
é um exemplo de como pode ser como o<--
operador.Respostas:
Isso é chamado de operador de comparação de três vias .
De acordo com a proposta do documento P0515 :
A cppreference diz:
fonte
<0
", "compara>0
" e "compara==0
" significa, eles significam que o<=>
retorno é um valor negativo, positivo ou zero, dependendo dos argumentos. Muito parecidostrncmp
ememcmp
.'a' < 'a'
e ambos'c' < 'a'
sejam falsos,'a' < 'a'
e'a' < 'c'
não são. Em ordem forte, o seguinte é verdadeiro:a != b
→a < b || b < a
operator==(T x, T y) { return !(x < y) && !(y < x); }
eoperator!=(T x, T y) { return (x < y) || (y < x); }
- ah-ha! É claro que isso é menos eficiente do que verdadeiro==
, pois invoca a comparação duas vezes, mas ainda é puro.< 0
com true. Ou seja, sea < b
então(a <=> b) < 0
é sempre verdade.Em 11/11/2017 , o comitê ISO C ++ adotou a proposta de Herb Sutter para o operador de comparação tripartida <=> "nave espacial" como um dos novos recursos adicionados ao C ++ 20 . No artigo intitulado Comparação consistente Sutter, Maurer e Brown demonstram os conceitos do novo design. Para uma visão geral da proposta, aqui está um trecho do artigo:
Categorias de comparação
Cinco categorias de comparação são definidas como
std::
tipos, cada um com os seguintes valores predefinidos:Conversões implícitas entre esses tipos são definidas da seguinte maneira:
strong_ordering
com valores {less
,equal
,greater
} converte implicitamente:weak_ordering
com valores {less
,equivalent
,greater
}partial_ordering
com valores {less
,equivalent
,greater
}strong_equality
com valores {unequal
,equal
,unequal
}weak_equality
com valores {nonequivalent
,equivalent
,nonequivalent
}weak_ordering
com valores {less
,equivalent
,greater
} converte implicitamente:partial_ordering
com valores {less
,equivalent
,greater
}weak_equality
com valores {nonequivalent
,equivalent
,nonequivalent
}partial_ordering
com valores {less
,equivalent
,greater
,unordered
} converte implicitamente:weak_equality
com valores {nonequivalent
,equivalent
,nonequivalent
,nonequivalent
}strong_equality
com valores {equal
,unequal
} converte implicitamente em:weak_equality
com valores {equivalent
,nonequivalent
}Comparação de três vias
O
<=>
token é introduzido. A sequência de caracteres<=>
simboliza para<= >
, no código-fonte antigo. Por exemplo,X<&Y::operator<=>
precisa adicionar um espaço para manter seu significado.O operador sobrecarregável
<=>
é uma função de comparação de três vias e tem precedência maior que<
e menor que<<
. Ele retorna um tipo que pode ser comparado com literal,0
mas outros tipos de retorno são permitidos, como suporte a modelos de expressão. Todos os<=>
operadores definidos no idioma e na biblioteca padrão retornam um dos 5std::
tipos de categorias de comparação mencionados acima .Para tipos de idiomas,
<=>
são fornecidas as seguintes comparações do mesmo tipo internas. Todos são constexpr , exceto onde indicado de outra forma. Essas comparações não podem ser chamadas de forma heterogênea usando promoções / conversões escalares.bool
tipos de integrante e ponteiro,<=>
retornastrong_ordering
.<=>
e existem heterogêneos embutidosoperator<=>(T*, nullptr_t)
. Somente comparações de ponteiros com o mesmo objeto / alocação são expressões constantes.<=>
retornapartial_ordering
e pode ser chamado de forma heterogênea, ampliando argumentos para um tipo de ponto flutuante maior.<=>
retorna o mesmo que o tipo subjacente da enumeração<=>
.nullptr_t
,<=>
retornastrong_ordering
e sempre produzequal
.T[N] <=> T[N]
retorna o mesmo tipo queT
's<=>
e executa comparação lexicográfica elemento a elemento. Não há<=>
para outras matrizes.void
não há<=>
.Para entender melhor o funcionamento interno deste operador, leia o documento original . Isso é exatamente o que eu descobri usando os mecanismos de pesquisa.
fonte
_equality
tipos morreram: resultou que<=>
funciona bem com os quatro operadores relacionais, mas não com os dois operadores de igualdade (embora exista algum açúcar sintático intenso para apoiar o caso comum em que você deseja todos eles).Esta resposta se tornou irrelevante desde que a página da Web referenciada mudou
A página da web que você está referenciando estava quebrada. Ele estava sendo editado muito naquele dia e partes diferentes não estavam sincronizadas. O status quando eu estava olhando era:
Na parte superior da página, lista os operadores de comparação existentes no momento (em C ++ 14). Não existe
<=>
lá.Na parte inferior da página, eles deveriam ter listado os mesmos operadores, mas enganaram e adicionaram esta sugestão futura.
gcc
ainda não sabe<=>
(e com-std=c++14
, nunca saberá), então pensa que você quis dizera <= > b
. Isso explica a mensagem de erro.Se você tentar a mesma coisa daqui a cinco anos, provavelmente receberá uma mensagem de erro melhor, algo como
<=> not part of C++14.
fonte
<=>
operador com o rótulo (desde C ++ 20), informando em qual versão do padrão o esperado. O rótulo de padrões é uma convenção que cppreference.com segue. É claro que você não tem um compilador que voltou em uma máquina do tempo para dar suporte a você, mas o cpprefernce diz (corretamente) o que esperar.