#include <iostream>
using namespace std;
struct EventReceiverBase {
virtual ~EventReceiverBase() { }
};
template<typename T>
struct EventReceiver : public virtual EventReceiverBase {
virtual void receiveEvent(T* pSender) = 0;
};
struct EventSender {
EventReceiverBase* pReceiver;
template<typename T>
void sendEvent(T* pSender) {
EventReceiver<T>* pCastedReceiver =
dynamic_cast<EventReceiver<T>*>(pReceiver);
// HERE IS THE PROBLEM
// pCastedReceiver is null. T is BaseSender. The pointer
// being casted is really of type EventReceiver<DerivedSender>*,
// but it tries to cast to EventReceiver<BaseSender>*, and that
// fails.
pCastedReceiver->receiveEvent(pSender);
}
};
template<typename T>
struct BaseSender : public virtual EventSender {
void f() {
sendEvent((T*)this);
}
};
struct DerivedSender : public BaseSender<DerivedSender> {
};
struct MyClass : public virtual EventReceiver<DerivedSender> {
void receiveEvent(DerivedSender* pSender) { }
};
int main() {
MyClass my;
DerivedSender derivedSender;
derivedSender.pReceiver = &my;
derivedSender.f();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBFdmVudFJlY2VpdmVyQmFzZSB7CiAgICB2aXJ0dWFsIH5FdmVudFJlY2VpdmVyQmFzZSgpIHsgfQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IEV2ZW50UmVjZWl2ZXIgOiBwdWJsaWMgdmlydHVhbCBFdmVudFJlY2VpdmVyQmFzZSB7CiAgICB2aXJ0dWFsIHZvaWQgcmVjZWl2ZUV2ZW50KFQqIHBTZW5kZXIpID0gMDsKfTsKCnN0cnVjdCBFdmVudFNlbmRlciB7CiAgICBFdmVudFJlY2VpdmVyQmFzZSogcFJlY2VpdmVyOwoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICB2b2lkIHNlbmRFdmVudChUKiBwU2VuZGVyKSB7CiAgICAgICAgRXZlbnRSZWNlaXZlcjxUPiogcENhc3RlZFJlY2VpdmVyID0KICAgICAgICAgICAgZHluYW1pY19jYXN0PEV2ZW50UmVjZWl2ZXI8VD4qPihwUmVjZWl2ZXIpOwogICAgICAgIC8vIEhFUkUgSVMgVEhFIFBST0JMRU0KICAgICAgICAvLyBwQ2FzdGVkUmVjZWl2ZXIgaXMgbnVsbC4gVCBpcyBCYXNlU2VuZGVyLiBUaGUgcG9pbnRlcgogICAgICAgIC8vIGJlaW5nIGNhc3RlZCBpcyByZWFsbHkgb2YgdHlwZSBFdmVudFJlY2VpdmVyPERlcml2ZWRTZW5kZXI+KiwKICAgICAgICAvLyBidXQgaXQgdHJpZXMgdG8gY2FzdCB0byBFdmVudFJlY2VpdmVyPEJhc2VTZW5kZXI+KiwgYW5kIHRoYXQKICAgICAgICAvLyBmYWlscy4KICAgICAgICBwQ2FzdGVkUmVjZWl2ZXItPnJlY2VpdmVFdmVudChwU2VuZGVyKTsKICAgIH0KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBCYXNlU2VuZGVyIDogcHVibGljIHZpcnR1YWwgRXZlbnRTZW5kZXIgewogICAgdm9pZCBmKCkgewogICAgICAgIHNlbmRFdmVudCgoVCopdGhpcyk7CiAgICB9Cn07CnN0cnVjdCBEZXJpdmVkU2VuZGVyIDogcHVibGljIEJhc2VTZW5kZXI8RGVyaXZlZFNlbmRlcj4gewp9OwoKc3RydWN0IE15Q2xhc3MgOiBwdWJsaWMgdmlydHVhbCBFdmVudFJlY2VpdmVyPERlcml2ZWRTZW5kZXI+IHsKICAgIHZvaWQgcmVjZWl2ZUV2ZW50KERlcml2ZWRTZW5kZXIqIHBTZW5kZXIpIHsgfQp9OwoKaW50IG1haW4oKSB7CiAgICBNeUNsYXNzIG15OwogICAgRGVyaXZlZFNlbmRlciBkZXJpdmVkU2VuZGVyOwogICAgZGVyaXZlZFNlbmRlci5wUmVjZWl2ZXIgPSAmbXk7CiAgICBkZXJpdmVkU2VuZGVyLmYoKTsKICAgIHJldHVybiAwOwp9