Selon cppreference.com , std::rel_ops::operator!=,>,=
obsolète en C ++ 20.
Quelle est la raison derrière?
En C ++ 20, vous obtenez une comparaison à trois voies (opérateur <=>
), qui “génère” automatiquement des comparaisons par défaut si elles sont fournies:
struct A { // You only need to implement a single operator. std::strong_ordering operator<=>(const A&) const; }; // Comstackr generates all 6 relational operators A to1, to2; if (to1 == to2) { /* ... */ } // ok if (to1 <= to2) { /* ... */ } // ok, single call to <=>
La comparaison à trois voies std::rel_ops
nombreux avantages par rapport à std::rel_ops
, ce qui explique probablement pourquoi les opérateurs std::rel_ops
sont obsolètes. Sur le dessus de ma tête:
Il est plus polyvalent puisque, selon le type de retour d’ operator<=>
( std::strong_ordering
, std::weak_ordering
, …), seuls les opérateurs pertinents sont générés. Voir l’en-tête
pour plus d’informations.
Vous n’apportez pas un tas de surcharges d’opérateurs using namespace std::rel_ops
un modèle en using namespace std::rel_ops
.
Vous pouvez demander au compilateur de générer pour vous l’opérateur à trois voies en le configurant par défaut ( auto operator<=>(A const&) = default
) – Ceci générera essentiellement une comparaison lexicographique des classes de base et des membres de données non statiques, en plus déduira le bon type de commande si le type de retour est auto
.
Quelle est la raison derrière?
rel_ops
est déconseillé par le support de la bibliothèque pour l’opérateur Spaceship (Comparison) . Le papier ne liste aucune motivation, mais il apparaît dans le papier du vaisseau spatial :
Cela englobe l’espace de noms
std::rel_ops
, nous proposons donc également de supprimer (ou destd::rel_ops
obsolète)std::rel_ops
.
Il y a quatre raisons mentionnées dans le document (y compris la correction et la performance). Mais un gros std::rel_ops
qui n’est pas mentionné dans les deux documents est que std::rel_ops
ne std::rel_ops
tout simplement pas. La règle de base est que les opérateurs sont trouvés en utilisant ADL. rel_ops
ne vous donne pas les opérateurs ADL-trouvables, il déclare simplement les modèles de fonctions non contraintes comme:
namespace std { namespace rel_ops { template< class T > bool operator!=( const T& lhs, const T& rhs ) { return !(lhs == rhs); } } }
Donc, en utilisant des algorithmes comme:
struct X { ... }; bool operator<(X const&, X const&) { ... }; std::sort(values.begin(), values.end(), std::greater<>{});
Cela ne fonctionne tout simplement pas, sauf si vous vous assurez de:
#include using namespace std::rel_ops;
De manière assez homogène partout où vous en êtes le premier à inclure pour vous assurer que ces opérateurs sont visibles au moment de la définition de chaque modèle de fonction que vous pouvez éventuellement appeler.
Donc, l’ operator<=>
est simplement ssortingctement supérieur:
<=>
) au lieu de deux ( ==
et <
) = default
) C ++ 20 fournit une comparaison à trois voies , si bien que les uniques deviennent obsolètes.