Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using make_tuple for comparison [duplicate]

Possible Duplicate:
Implementing comparision operators via 'tuple' and 'tie', a good idea?

sometimes I need to write some ugly functors
e.g.

lhs.date_ < rhs.date_ ||
lhs.date_ == rhs.date_ && lhs.time_ < rhs.time_ ||
lhs.date_ == rhs.date_ && lhs.time_ == rhs.time_ && lhs.id_ < rhs.id_ .....

it really annoyed me.
So I started avoiding that writing following:

std::make_tuple( lhs.date_, lhs.time_, lhs.id_ ) < 
    std::make_tuple(rhs.date_, rhs.time_, rhs.id_ );

and I am almost happy, but mind that I'm probably using tuples not by their purpose makes me worry.

Could you criticize this solution?
Or it's a good practice?
How do you avoid such comparisons?

UPDATE:
Thanks for pointing on std::tie to avoid copying objects.
And thanks for pointing on duplicate question

like image 543
bayda Avatar asked May 29 '12 20:05

bayda


1 Answers

The declaration of std::tuple comparison operators states that:

Compares lhs and rhs lexicographically, that is, compares the first elements, if they are equivalent, compares the second elements, if those are equivalent, compares the third elements, and so on.

So what you are doing, other than having the possibility of creating unneeded temporaries (probably optimized away), seems ok to me.

Note that equivalent means !( lhs < rhs ) && !( rhs < lhs ) and not lhs == rhs, that's equality. Assuming equivalent and equality mean the same for your class, this would be ok. Note that this is no different than, for instance, accessing a set/map by key.

In order to avoid the temporaries, you can use std::tie which makes a tuple of lvalue references to its arguments:

std::tie( lhs.date_, lhs.time_, lhs.id_ ) < 
    std::tie( rhs.date_, rhs.time_, rhs.id_ );

In a similar fashion, std::forward_as_tuple makes a tuple of rvalue references.

like image 91
K-ballo Avatar answered Oct 06 '22 23:10

K-ballo