#Casting std::shared_ptr<Base> to std::shared_ptr<T>, where T is a class derived from Base

9 messages · Page 1 of 1 (latest)

brazen rune
#

This is my attempt:

class A {
    public:
    void testA(){
        std::cout << "A" << std::endl;
    }
};

class B : public A{
    public:
    void testB(){
        std::cout << "B" << std::endl;
    }
};

template <typename T>
std::shared_ptr<T> getBase(std::shared_ptr<A> a){
    return std::dynamic_pointer_cast<T>(a);
}


int main()
{
    auto b = std::make_shared<B>();
    std::shared_ptr<A> a = b;
    a->testA();
    
    
    auto c = getBase<B>(a);
    c->testB();

    return 0;
}

Unfortunately it doesn't compile. Am I doing sth wrong?

upbeat bobcatBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

lilac badge
#

Kinda, I don't think you are allowed to do something like that. Having two shared pointers point to the same object with different types

#

Why would you want to do that?

brazen rune
#

I'm making an entity component system

#

I store components as std::vector<std::unordered_map<EntityID, std::shared_ptr<Component>>> components;, where Component is the base class

#

I can easily get this to work with c style pointers and cast

template <typename T>
T* getBase(A* a){
    return (T*)a;
}

int main()
{
    B* b = new B;

    A* a = b;
    a->testA();
    
    b = getBase<B>(a);
    b->testB();

    return 0;
}

But I was wandering if I could do this on smart pointers instead

#

As it turns out I can use std::reinterpret_pointer_cast<T>(a);. How bad of an idea is it?

#

Btw, I'm vaguely aware that reinterpret cast essentailly tells the compiler to treat bits at the specific address as bits of a different type