Convenient way to define all comparison operators for class with one numeric data member?

后端 未结 3 1218
眼角桃花
眼角桃花 2021-01-13 13:08

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

相关标签:
3条回答
  • 2021-01-13 13:54

    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));
    }
    
    0 讨论(0)
  • 2021-01-13 14:03

    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.

    0 讨论(0)
  • 2021-01-13 14:14

    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;
    }
    
    0 讨论(0)
提交回复
热议问题