/ / std :: map, type de clé personnalisé avec tri uniquement sur une variable - c ++, map, operators, std

std :: map, type de clé personnalisé avec tri uniquement sur une variable - c ++, map, operators, std

J'ai un type de clé:

struct KeyT {
uint32_t timestamp;

// example!
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
uint32_t e;
// ...

bool operator== (const KeyT& key) const
{
if(timestamp == key.timestamp && a == key.a && b == key.b && d == key.d && c == key.c && e == key.e)
return true;
return false;

}
bool operator< (const KeyT& key) const
{
if(timestamp < key.timestamp)
return true;
else if(timestamp == key.timestamp && a < key.a && b < key.b && c < key.c && d < key.d && e < key.e)
return true;
else if(timestamp == key.timestamp && a == key.a && b < key.b && c < key.c && d < key.d && e < key.e)
return true;
else if(timestamp == key.timestamp && a == key.a && b == key.b && c < key.c && d < key.d && e < key.e)
return true;
else if(timestamp == key.timestamp && a == key.a && b == key.b && c == key.c && d < key.d && e < key.e)
return true;
else if(timestamp == key.timestamp && a == key.a && b == key.b && c == key.c && d == key.d && e < key.e)
return true;
// ..
return false;
}
};

Maintenant, je ne me soucie pas vraiment du tri surLes membres vars a, b, c, d, e, la seule chose que je veux m'assurer, c'est que la carte est triée sur l'horodatage. Je viens aussi de réaliser que si j'ai deux instances de KeyT un, deux, où tout est le même sauf pour "d", alors les deux un <deux et deux <un seraient faux. La seule façon de résoudre ce problème est d'écrire des comparaisons pour toutes les combinaisons possibles de toutes les variables de membre. Je suis pratiquement certain qu'il me manque quelque chose d'évident, alors quelle est la meilleure solution dans ce cas?

Merci!

Réponses:

6 pour la réponse № 1

Je pense que cela fait ce dont vous avez besoin:

bool operator< (const KeyT& key) const
{
if(timestamp != key.timestamp) return timestamp < key.timestamp;
else if ( a != key.a ) return a < key.a;
else if ( b != key.b ) return b < key.b;
else if ( c != key.c ) return c < key.c;
else if ( d != key.d ) return d < key.d;
else return e < key.e;
}

Il s'agit d'un modèle judicieux mais laid à utiliser chaque fois que vous avez une liste prioritaire de variables que vous souhaitez trier dans une classe comparable.


1 pour la réponse № 2

Tout d'abord, vous devez comparer uniquement la clé actuelle suivante qui n'a pas été comparée pour être inférieure à, et supprimer le else après return, comme ça:

bool operator< (const KeyT& key) const
{
if(timestamp < key.timestamp)
return true;
if(timestamp == key.timestamp && a < key.a)
return true;
if(timestamp == key.timestamp && a == key.a && b < key.b)
return true;
if(timestamp == key.timestamp && a == key.a && b == key.b && c < key.c)
return true;
if(timestamp == key.timestamp && a == key.a && b == key.b && c == key.c && d < key.d)
return true;
if(timestamp == key.timestamp && a == key.a && b == key.b && c == key.c && d == key.d && e < key.e)
return true;
// ..
return false;
}

Si vous devez comparer uniquement l'horodatage, laissez le premier ifet supprimez les autres:

bool operator< (const KeyT& key) const
{
return timestamp < key.timestamp;
}

Lorsque vous utilisez cet opérateur pour comparer vos clés, les éléments avec un horodatage identique ne seront pas réorganisés.


0 pour la réponse № 3

Si tout ce qui vous intéresse, c'est l'horodatage etd'autres attributs n'ont pas d'importance, vous pouvez utiliser ce qui suit qui est un ordre faible strict. Vous ne saurez jamais dans quel ordre les objets du même horodatage apparaîtront:

bool operator< (const KeyT& key) const
{
return timestamp < key.timestamp;
}

Si vous avez besoin de commander sur tous les attributs que je suggère boost::tie:

bool operator< (const KeyT& key) const
{
return boost::tie(timestamp, a, b, c, d, e) < boost::tie(key.timestamp, key.a, key.b, key.c, key.d, e.key);
}