Question
Comment définir operator<
sur n-uplet (par exemple le 3-tuple) de manière à satisfaire la commande faible stricte concept? Je sais que la bibliothèque Boost a classe tuple avec operator<
correctement défini, mais pour certaines raisons, je ne peux pas l'utiliser.
La solution
if (a1 < b1)
return true;
if (b1 < a1)
return false;
// a1==b1: continue with element 2
if (a2 < b2)
return true;
if (b2 < a2)
return false;
// a2 == b2: continue with element 3
if (a3 < b3)
return true;
return false; // early out
Cette commande les éléments par a1 étant le plus siginificant et a3 moins significatif.
Cela peut se poursuivre ad infinitum, vous pouvez aussi par exemple appliquer à un vecteur de T, l'itération sur les comparaisons d'un [i]
Bien sûr, si la comparaison est cher, vous voudrez peut-être mettre en cache le résultat de la comparaison. [modifier] code erroné supprimé [modifier] si plus que while (i<count-1 && !(a[i] < a[i+1]) && !(a[i+1] < a[i])
++i;
return i < count-1 && a[i] < a[i+1];
operator<
est disponible, j'ai tendance à utiliser le modèle if (a1 != b1)
return a1 < b1;
if (a2 != b2)
return a2 < b2;
...
Autres conseils
commande stricte faible
Ceci est un terme mathématique pour définir une relation entre deux objets.
Sa définition est:
Deux objets x et y sont équivalentes si les deux f (x, y) et f (y, x) sont fausses. Notez qu'un objet est toujours (par l'invariant de irréflexivité) équivalent à lui-même.
En termes de C ++ cela signifie que si vous avez deux objets d'un type donné, vous devez retourner les valeurs suivantes par rapport à l'opérateur <.
X a;
X b;
Condition: Test: Result
a is equivalent to b: a < b false
a is equivalent to b b < a false
a is less than b a < b true
a is less than b b < a false
b is less than a a < b false
b is less than a b < a true
Comment vous définissez équivalent / moins est totalement dépendant du type de votre objet.
Informatique:
Strict faible de commande
... une nouvelle réponse à une question très ancienne, mais la réponse existante manquez pas la solution facile de 11 C ++ ...
C ++ 11 solution
C ++ 11 partir fournit std::tuple<T...>
, que vous pouvez utiliser pour stocker vos données. tuple
s ont une correspondance operator<
qui compare d'abord la gauche élément le plus, puis travaille le long de la tuple jusqu'à le résultat est clair. C'est apte à fournir le faible ordre strict attendu par exemple std::set
et std::map
.
Si vous avez des données dans d'autres variables (par exemple les champs dans un struct
), vous pouvez même utiliser std::tie()
crée un tuple de références , qui peut alors être comparé à un autre tuple tel. Cela le rend facile d'écrire pour operator<
spécifiques champs membres-données dans un class
défini par l'utilisateur / type struct
:
struct My_Struct
{
int a_;
double b_;
std::string c_;
};
bool operator<(const My_Struct& lhs, const My_Struct& rhs)
{
return std::tie(lhs.a_, lhs.b_, lhs.c_) < std::tie(rhs.a_, rhs.b_, rhs.c_);
}
Vous pouvez simplement utiliser des vecteurs à trois éléments, qui déjà l'opérateur <() convenablement défini. Ceci a l'avantage qu'il étend à N-éléments sans avoir à faire quoi que ce soit.
devrait être le long des lignes du flux de base: si les éléments KTH sont différents, retour qui est plus petit bien aller à l'élément suivant . Le code suivant suppose que vous ne pas ont un tuple boost sinon vous utiliserait get<N>(tuple)
et ne pas avoir le problème pour commencer.
if (lhs.first != rhs.first)
return lhs.first < rhs.first;
if (lhs.second != rhs.second)
return lhs.second< rhs.second;
return lhs.third < rhs.third;
Même si vous ne pouvez pas utiliser la version boost, vous devriez être en mesure entailler le code. J'entaillé ce std :: paire - un 3 tuple sera similaire Je suppose que
.return (_Left.first < _Right.first ||
!(_Right.first < _Left.first) && _Left.second < _Right.second);
Edit:. En tant que couple de personnes ont souligné, si vous volez le code de la bibliothèque standard à utiliser dans votre code, vous devez renommer les choses qui ont underscores sur l'avant que ces noms sont réservés