If I have a type that consists of a single numeric data member (say, an int
) and various methods, is there a convenient way to tell the compiler to automaticall
The C++ way of doing this is to use a tag type and ADL. Here is a quick example:
namespace relational {
struct tag {};
template <typename T>
bool operator== (T const& lhs, T const& rhs) { return !(rhs < lhs) && !(lhs < rhs); }
template <typename T>
bool operator!= (T const& lhs, T const& rhs) { return !(lhs == rhs); }
template <typename T>
bool operator> (T const& lhs, T const& rhs) { return rhs < lhs; }
template <typename T>
bool operator<= (T const& lhs, T const& rhs) { return !(rhs < lhs); }
template <typename T>
bool operator>= (T const& lhs, T const& rhs) { return !(lhs < rhs); }
}
struct foo: relational::tag {
int value;
foo(int value): value(value) {}
bool operator< (foo const& other) const { return this->value < other.value; }
};
#include <iostream>
void compare(foo f0, foo f1) {
std::cout << std::boolalpha
<< f0.value << " == " << f1.value << " => " << (f0 == f1) << '\n'
<< f0.value << " != " << f1.value << " => " << (f0 != f1) << '\n'
<< f0.value << " < " << f1.value << " => " << (f0 < f1) << '\n'
<< f0.value << " <= " << f1.value << " => " << (f0 <= f1) << '\n'
<< f0.value << " > " << f1.value << " => " << (f0 > f1) << '\n'
<< f0.value << " >= " << f1.value << " => " << (f0 >= f1) << '\n'
;
}
int main() {
compare(foo(1), foo(2));
compare(foo(2), foo(2));
}
Have you looked at boost operators (http://www.boost.org/doc/libs/1_56_0/libs/utility/operators.htm)? It defines a bunch of templates to help you automatically define operators in your class.
While in general ADL/KL is blessed way to go (kudos to Dietmar Kuhl), there is Curiously Recurring Template Pattern which might be used to facilitate such task (I've implemented not all methods, but idea is clear enough, I hope)
template <typename D> struct B
{
bool operator==(const D& rhs) const { return !(rhs < *(const D*)this ) && !(*(const D*)this < rhs); }
bool operator!=(const D& rhs) const { return !(*(const D*)this == rhs); }
};
struct D: public B<D>
{
int _value;
D(int value): _value(value) {}
bool operator< (const D& rhs) const {return this->_value < rhs._value;}
};
int main()
{
D a(1);
D b(2);
D c(1);
std::cout << (a == b) << " " << (a == c) << " " << (a != c) << std::endl;
return 0;
}