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.

Était-ce utile?

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]

while (i<count-1 && !(a[i] < a[i+1]) && !(a[i+1] < a[i])
  ++i;
return i < count-1 && a[i] < a[i+1];

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 operator< est disponible, j'ai tendance à utiliser le modèle

if (a1 != b1)
  return a1 < b1;

if (a2 != b2)
  return a2 < b2;

...

Autres conseils

... 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. tuples 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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top