问题
I have a key type:
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;
}
};
Now, I don't really care about the sorting on member vars a, b, c, d, e, the only thing I want to ensure is that the map is sorted on timestamp. I also just realized that if I have two instances of KeyT one, two, where everything is the same except for "d", then both one < two, and two < one would be false. The only way to fix that is to write comparisons for all possible combinations of all member variables.. I'm fairly certain I'm missing something obvious, so what's the best solution in this case?
Thanks!
回答1:
I think this does what you need:
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;
}
This is a sensible if ugly pattern to use whenever you have a prioritised list of variables you want to sort on within a comparable class.
回答2:
First, you should compare only the next current key that has not been compared for being less than, and drop the else
after return
, like this:
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;
}
If you need to compare only the timestamp, leave the first if
, and delete the remaining ones:
bool operator< (const KeyT& key) const
{
return timestamp < key.timestamp;
}
When you use this operator for comparing your keys, the items with identical timestamp will not be reordered.
回答3:
If all you care about is the timestamp, and the other attributes just don't matter, you can use the following which is a strict weak ordering. You'll just never know what order the objects of the same timestamp will appear:
bool operator< (const KeyT& key) const
{
return timestamp < key.timestamp;
}
If you need to order on all the attributes I suggest 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);
}
来源:https://stackoverflow.com/questions/11317538/stdmap-custom-key-type-with-sorting-only-on-one-variable