Home > database >  C Reuse out-of-class comparsion operators of base for derived class
C Reuse out-of-class comparsion operators of base for derived class

Time:11-06

Snippet

struct A {
    int a;
};

bool operator==(const A& lhs, const A& rhs) { return lhs.a == rhs.a; }

template <typename T>
bool operator==(const A& lhs, const T& rhs) {
    return lhs.a == rhs;
}

template <typename T>
bool operator==(const T& rhs, const A& lhs) {
    return lhs.a == rhs;
}

struct B : public A {
};

int main() {
    A a1, a2;
    B b1, b2;

    auto c1 = a1 == a2;
    auto c2 = static_cast<A>(b1) == static_cast<A>(b2);
    auto c3 = b1 == b2;
}

Is it possible to make the last comparison b1 == b2 work without a static_cast? Is a reuse of the out-of-class comparison operators of A possible without redefining explicit comparison operators for B?

Example on godbolt

EDIT: I forgot to mention that A is immutable to me. I have no access to it and its comparison operators.

CodePudding user response:

Is it possible to make the last comparison b1 == b2 work without a static_cast?

Yes, you can use SFINAE as shown below:

bool operator==(const A& lhs, const A& rhs) { return lhs.a == rhs.a; }

template <typename T>
typename std::enable_if_t<!std::is_same_v<T, B>, bool > operator==(const A& lhs, const T& rhs) {
    return lhs.a == rhs;
}

template <typename T>
typename std::enable_if_t<!std::is_same_v<T, B>,bool> operator==(const T& rhs, const A& lhs) {
    return lhs.a == rhs;
}
int main() {
    A a1, a2;
    B b1, b2;

    auto c1 = a1 == a2;
    auto c2 = b1 == b2; //works now 
    auto c3 = b1 == b2;
}

Working demo.


Or with C 20 use requires

bool operator==(const A& lhs, const A& rhs) { return lhs.a == rhs.a; }

template <typename T> bool operator==(const A& lhs, const T& rhs) 
requires (!std::is_same_v<T, B>)
{
    return lhs.a == rhs;
}

template <typename T>bool  operator==(const T& rhs, const A& lhs) 
requires (!std::is_same_v<T, B>)
{
    return lhs.a == rhs;
}

Demo

  • Related