#include <iostream>
struct Base
{
public:
virtual ~Base() {};
};
struct Derived1 : Base
{
int x = 42;
};
struct Derived2 : Base
{
double z = 33.33;
};
struct Mixed : Derived1, Derived2
{
};
struct Unrelated
{
virtual ~Unrelated(){}
};
struct TypeTag
{
virtual ~TypeTag(){}
};
template <typename T>
struct TypeTagSpec : virtual TypeTag
{
};
template <>
struct TypeTagSpec<Unrelated> : virtual TypeTag
{
};
template <>
struct TypeTagSpec<Base> : virtual TypeTag
{
};
template <>
struct TypeTagSpec<Derived1> : virtual TypeTagSpec<Base>
{
};
template <>
struct TypeTagSpec<Mixed> : virtual TypeTagSpec<Derived1>, virtual TypeTagSpec<Derived2>
{
};
// The "solution"
template <typename T>
T *isRelated(void *obj, void *tag)
{
const TypeTag *typetag = reinterpret_cast<TypeTag*>(tag);
if(dynamic_cast<const TypeTagSpec<T>*>(typetag))
return reinterpret_cast<T*>(obj);
return nullptr;
}
int main()
{
Mixed *mixed = new Mixed();
TypeTag *typetag = new TypeTagSpec<Mixed>();
// Test begins here
void *obj = mixed;
void *tag = typetag;
Derived1* d1 = isRelated<Derived1>(obj, tag);
Derived2* d2 = isRelated<Derived2>(obj, tag);
if (d1) std::cout << d1->x << "\n";
if (d2) std::cout << d2->z << "\n";
delete mixed;
delete typetag;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IEJhc2UKewpwdWJsaWM6CiAgdmlydHVhbCB+QmFzZSgpIHt9Owp9OwoKc3RydWN0IERlcml2ZWQxIDogQmFzZQp7CiAgIGludCB4ID0gNDI7Cn07CgpzdHJ1Y3QgRGVyaXZlZDIgOiBCYXNlCnsKICBkb3VibGUgeiA9IDMzLjMzOwp9OwoKc3RydWN0IE1peGVkIDogRGVyaXZlZDEsIERlcml2ZWQyCnsKfTsKCnN0cnVjdCBVbnJlbGF0ZWQKewogICAgdmlydHVhbCB+VW5yZWxhdGVkKCl7fQp9OwoKc3RydWN0IFR5cGVUYWcKewogIHZpcnR1YWwgflR5cGVUYWcoKXt9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IFR5cGVUYWdTcGVjIDogdmlydHVhbCBUeXBlVGFnCnsKfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBUeXBlVGFnU3BlYzxVbnJlbGF0ZWQ+IDogdmlydHVhbCBUeXBlVGFnCnsKfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBUeXBlVGFnU3BlYzxCYXNlPiA6IHZpcnR1YWwgVHlwZVRhZwp7Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgVHlwZVRhZ1NwZWM8RGVyaXZlZDE+IDogdmlydHVhbCBUeXBlVGFnU3BlYzxCYXNlPgp7Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgVHlwZVRhZ1NwZWM8TWl4ZWQ+IDogdmlydHVhbCBUeXBlVGFnU3BlYzxEZXJpdmVkMT4sIHZpcnR1YWwgVHlwZVRhZ1NwZWM8RGVyaXZlZDI+CnsKfTsKCi8vIFRoZSAic29sdXRpb24iCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpUICppc1JlbGF0ZWQodm9pZCAqb2JqLCB2b2lkICp0YWcpCnsKICBjb25zdCBUeXBlVGFnICp0eXBldGFnID0gcmVpbnRlcnByZXRfY2FzdDxUeXBlVGFnKj4odGFnKTsKICBpZihkeW5hbWljX2Nhc3Q8Y29uc3QgVHlwZVRhZ1NwZWM8VD4qPih0eXBldGFnKSkKICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFQqPihvYmopOwogIHJldHVybiBudWxscHRyOwp9CgppbnQgbWFpbigpCnsKICBNaXhlZCAqbWl4ZWQgPSBuZXcgTWl4ZWQoKTsKICBUeXBlVGFnICp0eXBldGFnID0gbmV3IFR5cGVUYWdTcGVjPE1peGVkPigpOwoKICAvLyBUZXN0IGJlZ2lucyBoZXJlCiAgdm9pZCAqb2JqID0gbWl4ZWQ7CiAgdm9pZCAqdGFnID0gdHlwZXRhZzsKCiAgRGVyaXZlZDEqIGQxID0gaXNSZWxhdGVkPERlcml2ZWQxPihvYmosIHRhZyk7CiAgRGVyaXZlZDIqIGQyID0gaXNSZWxhdGVkPERlcml2ZWQyPihvYmosIHRhZyk7CgogIGlmIChkMSkgc3RkOjpjb3V0IDw8IGQxLT54IDw8ICJcbiI7CiAgaWYgKGQyKSBzdGQ6OmNvdXQgPDwgZDItPnogPDwgIlxuIjsKCiAgZGVsZXRlIG1peGVkOwogIGRlbGV0ZSB0eXBldGFnOwp9