#include <iostream>
using namespace std;
class A
{
public:
bool operator==(const A& a) const
{
return equals(a);
}
protected:
virtual bool equals(const A& a) const = 0;
};
template<class T>
class A_ : public A
{
protected:
virtual bool equals(const A& a) const
{
const T* other = dynamic_cast<const T*>(&a);
return other != nullptr && static_cast<const T&>(*this) == *other;
}
private:
bool operator==(const A_& a) const // force derived classes to implement their own operator==
{
return false;
}
};
class B : public A_<B>
{
public:
B(int i) : id(i) {}
bool operator==(const B& other) const
{
return id == other.id;
}
private:
int id;
};
class C : public A_<C>
{
public:
C(int i) : identity(i) {}
bool operator==(const C& other) const
{
return identity == other.identity;
}
private:
int identity;
};
const char * TF(bool b)
{
return b ? "True" : "False";
}
int main() {
B b1(1);
B b2(2);
C c1(1);
C c2(1);
A& a1 = b1;
A& a2 = b2;
A& a3 = c1;
A& a4 = c2;
cout << "a1 == b1: " << TF(a1 == b1) << endl;
cout << "a1 == a2: " << TF(a1 == a2) << endl;
cout << "a2 == a3: " << TF(a2 == a3) << endl;
cout << "a3 == a4: " << TF(a3 == a4) << endl;
// your code goes here
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgQQp7CnB1YmxpYzoKCWJvb2wgb3BlcmF0b3I9PShjb25zdCBBJiBhKSBjb25zdAoJewoJCXJldHVybiBlcXVhbHMoYSk7Cgl9CnByb3RlY3RlZDoKCXZpcnR1YWwgYm9vbCBlcXVhbHMoY29uc3QgQSYgYSkgY29uc3QgPSAwOwp9OwoKdGVtcGxhdGU8Y2xhc3MgVD4KY2xhc3MgQV8gOiBwdWJsaWMgQQp7CnByb3RlY3RlZDoKCXZpcnR1YWwgYm9vbCBlcXVhbHMoY29uc3QgQSYgYSkgY29uc3QKCXsKCQljb25zdCBUKiBvdGhlciA9IGR5bmFtaWNfY2FzdDxjb25zdCBUKj4oJmEpOwoJCXJldHVybiBvdGhlciAhPSBudWxscHRyICYmIHN0YXRpY19jYXN0PGNvbnN0IFQmPigqdGhpcykgPT0gKm90aGVyOwoJfQpwcml2YXRlOgoJYm9vbCBvcGVyYXRvcj09KGNvbnN0IEFfJiBhKSBjb25zdAkvLyBmb3JjZSBkZXJpdmVkIGNsYXNzZXMgdG8gaW1wbGVtZW50IHRoZWlyIG93biBvcGVyYXRvcj09Cgl7CgkJcmV0dXJuIGZhbHNlOwoJfQp9OwoKY2xhc3MgQiA6IHB1YmxpYyBBXzxCPgp7CnB1YmxpYzoKCUIoaW50IGkpIDogaWQoaSkge30KCWJvb2wgb3BlcmF0b3I9PShjb25zdCBCJiBvdGhlcikgY29uc3QKCXsKCQlyZXR1cm4gaWQgPT0gb3RoZXIuaWQ7Cgl9CnByaXZhdGU6CglpbnQgaWQ7Cn07CgpjbGFzcyBDIDogcHVibGljIEFfPEM+CnsKcHVibGljOgoJQyhpbnQgaSkgOiBpZGVudGl0eShpKSB7fQoJYm9vbCBvcGVyYXRvcj09KGNvbnN0IEMmIG90aGVyKSBjb25zdAoJewoJCXJldHVybiBpZGVudGl0eSA9PSBvdGhlci5pZGVudGl0eTsKCX0KcHJpdmF0ZToKCWludCBpZGVudGl0eTsKfTsKCmNvbnN0IGNoYXIgKiBURihib29sIGIpCnsKCXJldHVybiBiID8gIlRydWUiIDogIkZhbHNlIjsKfQoKaW50IG1haW4oKSB7CglCIGIxKDEpOwoJQiBiMigyKTsKCUMgYzEoMSk7CglDIGMyKDEpOwoJQSYgYTEgPSBiMTsKCUEmIGEyID0gYjI7CglBJiBhMyA9IGMxOwoJQSYgYTQgPSBjMjsKCWNvdXQgPDwgImExID09IGIxOiAiIDw8IFRGKGExID09IGIxKSA8PCBlbmRsOwoJY291dCA8PCAiYTEgPT0gYTI6ICIgPDwgVEYoYTEgPT0gYTIpIDw8IGVuZGw7Cgljb3V0IDw8ICJhMiA9PSBhMzogIiA8PCBURihhMiA9PSBhMykgPDwgZW5kbDsKCWNvdXQgPDwgImEzID09IGE0OiAiIDw8IFRGKGEzID09IGE0KSA8PCBlbmRsOwoJCgkvLyB5b3VyIGNvZGUgZ29lcyBoZXJlCglyZXR1cm4gMDsKfQ==