Home > front end >  Template specification for a derived class in an std::shared_ptr
Template specification for a derived class in an std::shared_ptr

Time:12-23

How would I provide a template specialisation for the Derived class in this simple case, assuming the Base cannot be changed - in my real code, Base is a library that I cannot change.

#include <iostream>
#include <memory>

class Base
{
    public:
        virtual void foo() { std::cout << "In base\n"; }
};

class Derived: public Base
{
    public:
        virtual void foo() { std::cout << "In derived\n"; }
};

template<typename T>
void wibble(T &&baz)
{
    std::cout << "In wibble for default\n";
    baz->foo();
}

// How do I provide a specialisation here?
//template<typename what_goes_here>
//void wibble(what_goes_here &&baz)
//{
//    std::cout << "In wibble for derived\n";
//    baz->foo();
//}

int main()
{
    std::shared_ptr<Base> bar = std::make_shared<Derived>();
    
    bar->foo();
    wibble(bar);

    return 0;
}

I want to be able to use a separate template when the actual type contained within the shared pointer is Derived.

CodePudding user response:

The proper tool here is to use dynamic_cast<Derived*>. This is runtime information and as such must be queried at runtime.

Something like

void wibble(std::shared_ptr<Base*> baz){
    if(auto derived =dynamic_cast<Derived*>(baz.get()){
       // user derived pointer.
    }
}

should allow you achieve something similar to what you want. If your keyboard is missing *, you can also (thanks Eljay)

if(auto derived = std::dynamic_pointer_cast<Derived>(baz){
    // use derived
}

This is just one more case where templates and polymorphism doesn't really play nice with each other, mainly because of the compile time/runtime dichotomy.

  • Related