
Kevin Spinar schrieb:
On 7/13/06, Christopher Eltschka <celtschk@web.de> wrote:
operator< and operator== of course can be defined anywhere the std::rel_ops operators will find them (e.g. they could be defined as class members instead).
Note that you really only have to define operator< as operator== could be written as
template<class T, class U> bool operator==(const T &lhs, const U &rhs) { return !(lhs < rhs) && !(rhs < lhs); }
and the user could still define operator== themselves for optimization purposes (then you should make sure to define operator!= in terms of operator==).
I would have expected an ambiguity in that case (because both are found with Koenig lookup), but a quick test with operator!= showed that at least with gcc, indeed it works! Thinking about it, it probably works because the one in std::rel_ops is a template, so the non-template operator== takes precedence. I'm not sure if there are reasonable cases where this would break with a templated user-defined operator. However, one could make different base classes providing dofferent set of operators, say class A: rel::ops_from_less { ... } derived all operators from operator< and class A: rel::ops_from_less_and_equal { ... } doesn't derive equal from less. One could also make a version which derives all those operators from a "3-way comparison function" a la strcmp. In that case one would have to select a standardized name for that function as well. Maybe just "compare3way"? In that case, maybe it would also make sense to define that function for the other cases (i.e. automatically derive compare3way from operator<).
Are you going to allow comparision of different types (like I showed above) or strictly comparision among objects of the same type?
Well, at the moment I just delegate to std::rel_ops, so only comparing strictly the same type is supported. However, it's trivial to change this (i.e. write those functions again with two separate template type arguments) so that arbitrary types can be compared. However I'm not sure if it's a good idea: After all, it might trigger in a situation where we don't want it (I'm not sure if such a situation could happen, however it's something one should consider).
Alternatively it could be extended to support other typical operator implementations not covered by the standard, e.g. defining operator@ in terms of operator@=.
Sounds good.
Doing some brainstorming, I get the following candidate list for useful automatic operators: * comparison operators from operator< and operator== * operator @ from operator @= * posfix operator++/-- from prefix one * unary operator+ (returning just the object) * maybe also binary - from + and unary -? Any other good candidates? Christopher Eltschka