#include <iostream>
#include <typeinfo>
using namespace std;
struct A {
virtual bool operator==(const A &other) const = 0;
};
template<typename Base, typename Derived>
struct PolymorphicComparable : public Base {
bool operator==(const Base &other) const {
if (typeid(other) != typeid(Derived))
return false;
const Derived & a = static_cast<const Derived&>(*this);
const Derived & b = static_cast<const Derived&>(other);
return a == b; // call Derived::operator==(Derived)
}
};
struct A1 : public PolymorphicComparable<A,A1>
{
int i;
A1(int i) : i(i) {}
bool operator==(const A1 &other) const {
return i == other.i;
}
};
struct A2 : public PolymorphicComparable<A,A2>
{
float f;
A2(float f) : f(f) {}
bool operator==(const A2 &other) const {
return f == other.f;
}
};
int main() {
A * a = new A1(5);
A * b = new A1(2);
A * c = new A2(7.6);
A * d = new A2(7.6);
// Comparing objects of same dynamic type:
cout << (*a == *b) << endl;
cout << (*c == *d) << endl;
// Comparing objects of different dynamic types:
cout << (*a == *c) << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzdHJ1Y3QgQSB7Cgl2aXJ0dWFsIGJvb2wgb3BlcmF0b3I9PShjb25zdCBBICZvdGhlcikgY29uc3QgPSAwOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgQmFzZSwgdHlwZW5hbWUgRGVyaXZlZD4Kc3RydWN0IFBvbHltb3JwaGljQ29tcGFyYWJsZSA6IHB1YmxpYyBCYXNlIHsKICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBCYXNlICZvdGhlcikgY29uc3QgewogICAgCWlmICh0eXBlaWQob3RoZXIpICE9IHR5cGVpZChEZXJpdmVkKSkKICAgIAkJcmV0dXJuIGZhbHNlOwogICAgCWNvbnN0IERlcml2ZWQgJiBhID0gc3RhdGljX2Nhc3Q8Y29uc3QgRGVyaXZlZCY+KCp0aGlzKTsKICAgIAljb25zdCBEZXJpdmVkICYgYiA9IHN0YXRpY19jYXN0PGNvbnN0IERlcml2ZWQmPihvdGhlcik7CiAgICAJcmV0dXJuIGEgPT0gYjsgLy8gY2FsbCBEZXJpdmVkOjpvcGVyYXRvcj09KERlcml2ZWQpCiAgICB9Cn07CgpzdHJ1Y3QgQTEgOiBwdWJsaWMgUG9seW1vcnBoaWNDb21wYXJhYmxlPEEsQTE+CnsKICAgIGludCBpOwogICAgQTEoaW50IGkpIDogaShpKSB7fQogICAgCiAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgQTEgJm90aGVyKSBjb25zdCB7CiAgICAJcmV0dXJuIGkgPT0gb3RoZXIuaTsKICAgIH0KfTsKCnN0cnVjdCBBMiA6IHB1YmxpYyBQb2x5bW9ycGhpY0NvbXBhcmFibGU8QSxBMj4KewogICAgZmxvYXQgZjsKICAgIEEyKGZsb2F0IGYpIDogZihmKSB7fQogICAgCiAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgQTIgJm90aGVyKSBjb25zdCB7CiAgICAJcmV0dXJuIGYgPT0gb3RoZXIuZjsKICAgIH0KfTsKCgppbnQgbWFpbigpIHsKCUEgKiBhID0gbmV3IEExKDUpOwoJQSAqIGIgPSBuZXcgQTEoMik7CglBICogYyA9IG5ldyBBMig3LjYpOwoJQSAqIGQgPSBuZXcgQTIoNy42KTsKCQoJLy8gQ29tcGFyaW5nIG9iamVjdHMgb2Ygc2FtZSBkeW5hbWljIHR5cGU6Cgljb3V0IDw8ICgqYSA9PSAqYikgPDwgZW5kbDsKCWNvdXQgPDwgKCpjID09ICpkKSA8PCBlbmRsOwoJCgkvLyBDb21wYXJpbmcgb2JqZWN0cyBvZiBkaWZmZXJlbnQgZHluYW1pYyB0eXBlczoKCWNvdXQgPDwgKCphID09ICpjKSA8PCBlbmRsOwoJCglyZXR1cm4gMDsKfQ==