it-swarm.dev

Co je operátor <=> v C ++?

Když jsem se snažil dozvědět se o operátorech C++ , narazil jsem na podivného operátora porovnání na cppreference.com ,* v tabulce, která vypadala takto:

enter image description here

"No, pokud jsou to běžní operátoři v C++, raději se je naučím," pomyslel jsem si. Ale všechny mé pokusy objasnit toto tajemství byly neúspěšné. Dokonce i tady, na Stack Overflow, jsem neměl ve svém hledání štěstí.

Existuje spojení mezi <=> a C++ ?

A pokud ano, co přesně tento operátor dělá?

* Mezitím cppreference.com tuto stránku aktualizoval a nyní obsahuje informace o operátoru <=>.

191
q-l-p

Dne 2017-11-11 přijal výbor ISO C++ Herb Sutter návrh na <=> "kosmickou loď" operátor porovnání cesty jako jedna z nových funkcí, které byly přidány do C++ 20 . V příspěvku s názvem konzistentní srovnání Sutter, Maurer a Brown demonstrují koncepty nového designu. Přehled návrhu je výňatek z článku:

Výraz a <=> b vrací objekt, který porovnává <0 pokud a <b , porovná > 0 , pokud a> b a porovnává == 0 , pokud a a b jsou stejné/ekvivalentní.

Častý případ: Chcete-li napsat všechna srovnání pro váš typ X s napište Y, s členskou sémantikou, stačí napsat:

auto X::operator<=>(const Y&) =default;

Pokročilé případy: Chcete-li zapsat všechna srovnání pro váš typ X s zadejte Y, stačí napsat operátor <=> , který vezme Y, lze použít = default k získání sémantiky členů, pokud je to žádoucí a vrátí příslušný typ kategorie:

  • Pokud váš typ přirozeně podporuje <, vraťte _ objednávání a my efektivně generovat symetrické <, > , <= , > = , == a ! = ; jinak vrátíme _ rovnost a efektivně vygenerujeme symetrické == a ! = .
  • Návrat silný _ , pokud pro váš typ a == b znamená f (a) == f (b) (nahraditelnost, kde f čte pouze srovnávací stav, který je přístupný pomocí veřejného const členů), jinak se vrací slabý _ .

Srovnávací kategorie

Pět kategorií srovnání je definováno jako typ std::, z nichž každá má následující předdefinované hodnoty:

+--------------------------------------------------------------------+
|                  |          Numeric  values          | Non-numeric |
|     Category     +-----------------------------------+             |
|                  | -1   | 0          | +1            |   values    |
+------------------+------+------------+---------------+-------------+
| strong_ordering  | less | equal      | greater       |             |
| weak_ordering    | less | equivalent | greater       |             |
| partial_ordering | less | equivalent | greater       | unordered   |
| strong_equality  |      | equal      | nonequal      |             |
| weak_equality    |      | equivalent | nonequivalent |             |
+------------------+------+------------+---------------+-------------+

Implicitní převody mezi těmito typy jsou definovány takto:

  • strong_ordering s hodnotami {less, equal, greater} implicitně převede na:
    • weak_ordering s hodnotami {less, equivalent, greater}
    • partial_ordering s hodnotami {less, equivalent, greater}
    • strong_equality s hodnotami {unequal, equal, unequal}
    • weak_equality s hodnotami {nonequivalent, equivalent, nonequivalent}
  • weak_ordering s hodnotami {less, equivalent, greater} implicitně převede na:
    • partial_ordering s hodnotami {less, equivalent, greater}
    • weak_equality s hodnotami {nonequivalent, equivalent, nonequivalent}
  • partial_ordering s hodnotami {less, equivalent, greater, unordered} implicitně převede na:
    • weak_equality s hodnotami {nonequivalent, equivalent, nonequivalent, nonequivalent}
  • strong_equality s hodnotami {equal, unequal} implicitně převede na:
    • weak_equality s hodnotami {equivalent, nonequivalent}

Třícestné srovnání

The<=>token je představen. Znaková posloupnost<=>tokenizes na<= >, ve starém zdrojovém kódu. Například X<&Y::operator<=>needs přidat mezeru, aby si zachoval svůj význam.

Operátor přetěžování<=> je funkce třícestného srovnání a má přednost vyšší než< a nižší než<<. Vrací typ, který lze porovnat s literal0but, ale jsou povoleny i jiné typy návratu, jako je podpora výrazových šablon. Všichni<=>operátoři definovaní v jazyce a ve standardní knihovně vrátí jeden z 5 výše uvedených typůstd::comparison kategorií.

U jazykových typů jsou poskytována následující vestavěná<=>same-type srovnání. Všechny jsou constexpr , pokud není uvedeno jinak. Tato srovnání nelze vyvolat heterogenně pomocí skalárních propagací/konverzí.

  • Forbool, integrity a typy ukazatelů, <=>returnsstrong_ordering.
  • U typů ukazatelů mohou různé převody cv a odvozené konverze vyvolat homogenní vestavěný<=> a jsou zabudovány heterogenníoperator<=>(T*, nullptr_t). Konstantní výrazy jsou pouze porovnání ukazatelů na stejný objekt/alokaci.
  • Pro základní typy s pohyblivou řádovou čárkou <=> vrátípartial_ordering a lze je vyvolat heterogenně rozšířením argumentů na větší typ s pohyblivou řádovou čárkou.
  • Pro výčty <=> vrací stejné jako základní typ výčtu's<=>.
  • Pronullptr_t, <=> se vracístrong_orderinga vždy se dáequal.
  • Pro kopírovatelná pole T[N] <=> T[N]returns stejný typ jakoT 's<=>and provede lexicographical elementwise srovnání. Neexistuje žádný<=> pro jiná pole.
  • Forvoidthere is no<=>.

Abyste lépe porozuměli vnitřním funkcím tohoto operátora, přečtěte si prosím originál papír . To je přesně to, co jsem zjistil pomocí vyhledávačů.

104
q-l-p

Tomu se říká operátor třícestného porovnání .

Podle P0515 papírového návrhu:

Je zde nový operátor třícestného srovnání <=>. Výraz a <=> b vrátí objekt, který porovná <0, pokud a < b, porovná >0, pokud a > b, a porovná ==0, pokud a a b jsou stejné/ekvivalentní.

Chcete-li napsat všechna srovnání pro váš typ, stačí napsat operator<=>, která vrátí příslušný typ kategorie:

  • Vraťte _ordering , pokud váš typ přirozeně podporuje < a my efektivně vygenerujeme <, >, <=, >=, == a !=; jinak vrátíme nerovnost a efektivně vygenerujeme == a ! = .

  • Vraťte se silně, pokud pro váš typ a == b znamená f(a) == f(b) (zastupitelnost, kde f čte pouze srovnávací stav přístupný pomocí netrivátního rozhraní const), jinak návrat slabý.

cppreference říká:

Výrazy operátorů třícestného porovnání mají podobu

lhs <=> rhs   (1)  

Výraz vrací objekt, který

  • porovnává <0, pokud lhs < rhs
  • porovnává >0, pokud lhs > rhs
  • a porovná ==0, pokud lhs a rhs jsou stejné/ekvivalentní.
166
msc

Tato odpověď se stala irelevantní, protože odkazovaná webová stránka se změnila

webová stránka, na kterou odkazujete byl poškozen. Toho dne bylo hodně upravováno a různé části nebyly synchronizovány. Stav, když jsem se na to díval, byl:

V horní části stránky je uveden seznam aktuálně existujících operátorů porovnání (v C++ 14). Neexistuje <=>there.

Ve spodní části stránky by měli být uvedeni stejní operátoři, ale šli do toho a přidali tento budoucí návrh.

gcc neví o <=>yet (as -std=c++14, nikdy nebude), takže si myslí, že jsi myslel a <= > b. To vysvětluje chybovou zprávu.

Pokud zkusíte stejnou věc po pěti letech, pravděpodobně dostanete lepší chybovou zprávu, například <=> not part of C++14.

11
Stig Hemmer