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;
}
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;
}