(Note: tuple
and tie
can be taken from Boost or C++11.)
When writing small structs with only two elements, I sometimes tend to choose a std::pair
, as all important stuff is already done for that datatype, like operator<
for strict-weak-ordering.
The downsides though are the pretty much useless variable names. Even if I myself created that typedef
, I won't remember 2 days later what first
and what second
exactly was, especially if they are both of the same type. This gets even worse for more than two members, as nesting pair
s pretty much sucks.
The other option for that is a tuple
, either from Boost or C++11, but that doesn't really look any nicer and clearer. So I go back to writing the structs myself, including any needed comparision operators.
Since especially the operator<
can be quite cumbersome, I thought of circumventing this whole mess by just relying on the operations defined for tuple
:
Example of operator<
, e.g. for strict-weak-ordering:
bool operator<(MyStruct const& lhs, MyStruct const& rhs){
return std::tie(lhs.one_member, lhs.another, lhs.yet_more) <
std::tie(rhs.one_member, rhs.another, rhs.yet_more);
}
(tie
makes a tuple
of T&
references from the passed arguments.)
Edit: The suggestion from @DeadMG to privately inherit from tuple
isn't a bad one, but it got quite some drawbacks:
- If the operators are free-standing (possibly friends), I need to inherit publicly
- With casting, my functions / operators (
operator=
specifically) can be easily bypassed - With the
tie
solution, I can leave out certain members if they don't matter for the ordering
Are there any drawbacks in this implementation that I need to consider?
tie
cannot be applied to bit-field members. – Radontie(...)
calls are going to be duplicated in various operators (=, ==, <, etc.) you could write a private inline methodmake_tuple(...)
to encapsulate that and then call it from the various other places, as inreturn lhs.make_tuple() < rhs.make_tuple();
(though the return type from that method could be fun to declare!) – Venalityauto tied() const{ return std::tie(the, members, here); }
– Gameto