#include <memory>
template<class T>
class Handle : public std::shared_ptr<T> {
public:
using std::shared_ptr<T>::shared_ptr;
template<class ResultType>
inline Handle<ResultType>
cast() const {
// Cast Handle to shared_ptr
auto T_sp = static_cast< std::shared_ptr<T> >(*this);
// Cast the data
auto ResultType_sp = std::static_pointer_cast<ResultType>(T_sp);
// Cast back to Handle
return static_cast< Handle<ResultType> >(ResultType_sp);
}
};
// Usage
struct Base {};
struct Child : public Base {};
int main() {
auto child_ptr = Handle<Child>(new Child());
auto base_ptr = child_ptr.cast<Base>(); // Error with this
return 0;
}
I2luY2x1ZGUgPG1lbW9yeT4KCnRlbXBsYXRlPGNsYXNzIFQ+CmNsYXNzIEhhbmRsZSA6IHB1YmxpYyBzdGQ6OnNoYXJlZF9wdHI8VD4gewpwdWJsaWM6Cgl1c2luZyBzdGQ6OnNoYXJlZF9wdHI8VD46OnNoYXJlZF9wdHI7CiAgICB0ZW1wbGF0ZTxjbGFzcyBSZXN1bHRUeXBlPgogICAgaW5saW5lIEhhbmRsZTxSZXN1bHRUeXBlPgogICAgY2FzdCgpIGNvbnN0IHsKICAgICAgICAvLyBDYXN0IEhhbmRsZSB0byBzaGFyZWRfcHRyCiAgICAgICAgYXV0byBUX3NwID0gc3RhdGljX2Nhc3Q8IHN0ZDo6c2hhcmVkX3B0cjxUPiA+KCp0aGlzKTsKICAgICAgICAvLyBDYXN0IHRoZSBkYXRhCiAgICAgICAgYXV0byBSZXN1bHRUeXBlX3NwID0gc3RkOjpzdGF0aWNfcG9pbnRlcl9jYXN0PFJlc3VsdFR5cGU+KFRfc3ApOwogICAgICAgIC8vIENhc3QgYmFjayB0byBIYW5kbGUKICAgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8IEhhbmRsZTxSZXN1bHRUeXBlPiA+KFJlc3VsdFR5cGVfc3ApOwogICAgfQp9OwoKCi8vIFVzYWdlCnN0cnVjdCBCYXNlIHt9OwpzdHJ1Y3QgQ2hpbGQgOiBwdWJsaWMgQmFzZSB7fTsKCmludCBtYWluKCkgewoJYXV0byBjaGlsZF9wdHIgPSBIYW5kbGU8Q2hpbGQ+KG5ldyBDaGlsZCgpKTsKCWF1dG8gYmFzZV9wdHIgID0gY2hpbGRfcHRyLmNhc3Q8QmFzZT4oKTsgLy8gRXJyb3Igd2l0aCB0aGlzCgkKCXJldHVybiAwOwp9