Consider a struct (as in: stupid aggergation of several members) with members that all implement a certain relation R
(e.g. <
):
struct X {
A a;
B b;
};
For most operators there exists a canonical definition for X R X
. For instance:
bool operator<(X const& x1, X const& x2) {
if ((x1.a < x2.a) || (x2.a < x1.a)) // I intentionally did not use != here
return x1.a < x2.a;
if ((x1.b < x2.b) || (x2.b < x1.b))
return x1.b < x2.b;
return false;
}
This is pretty boring to do for all operators, especially if you have quite some members and not only one such struct.
As you can see, operator<
over X
only relies on operator<
of its member types (A
,B
) besids the use of bool || bool
.
Is there a way to specify such operators generically (via templates or builtins?). Boost is not an option (but it would be interesting if it can do this, nevertheless).
It would be even greater if you could specify the evaluation order of the members (for speed).
Edit This question considers C++03, as otherwise you could use std::tuple
, I guess.
As apparently there is no non-boost solution, I brewed up some template magic, which I am posting as an answer in case somebody has the same problem;
Version 1: explicit arguments
Disclaimer: I know
BinaryFunctorMonad
is a slight misnomer, I just couldn't come up with something better.Version 2: inheritance
Yes boost can do it using tuple.
Thus you can do it yourself via templates. But the extra work to do that seems like a waste of time. Just do it the simple way with a function (though I don't like your logic).
The standard way:
The real normal way of doing it after compression
The way I used to like because it was clear.
Long winded tuple version
Short compact tuple version