I am having some problems with automatic typecasting between shared_ptr of inherited classes.
My class structure is as follows, a base class Base and two derived classes Derived1 and Derived2.
// Base class
class Base {
protected:
  ...
  ...
public:
  Base() = default;
  virtual ~Base() = default;
  virtual void run() = 0;
  ...
  ...
};
// Derived class
class Derived1: Base {
protected:
  ...
  ...
public:
  Derived1() = default;
  virtual ~Derived1() = default;
  void run() {...}
  ...
  ...
};
// Derived class
class Derived2: Base {
protected:
  ...
  ...
public:
  Derived2() = default;
  virtual ~Derived2() = default;
  void run() {...}
  ...
  ...
};
I have a function doSomething()
void doSomething(std::shared_ptr<Base> ptr) {
  ptr->run();
  ...
}
I call the function with the derived classes like so -
doSomething(make_shared<Derived1>())
doSomething(make_shared<Derived2>())
But I get an error saying -
no viable conversion from 'shared_ptr<class Derived1>' to 'shared_ptr<class Base>'
no viable conversion from 'shared_ptr<class Derived1>' to 'shared_ptr<class Base>'
What am I doing wrong? Is it safe just to use static_pointer_cast to the Base type? Like -
doSomething(static_pointer_cast<Base>(make_sahred<Derived2>()))
SOLUTION My bad... The problem was that I was inheriting the base class privately.
What is the technical problem with std::shared_ptr::unique() that is the reason for its deprecation in C++17? this function is deprecated as of C++17 because use_count is only an approximation in multi-threaded environment.
The difference is that std::make_shared performs one heap-allocation, whereas calling the std::shared_ptr constructor performs two.
Admittedly, the std::shared_ptr is about two times slower than new and delete. Even std::make_shared has a performance overhead of about 10%.
By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).
As far as I can tell, the code that you've presented compiles fine: http://ideone.com/06RB2W
#include <memory>
class Base {
    public:
        Base() = default;
        virtual ~Base() = default;
        virtual void run() = 0;
};
class Derived1: public Base {
    public:
        Derived1() = default;
        virtual ~Derived1() = default;
        void run() {}
};
class Derived2: public Base {
    public:
        Derived2() = default;
        virtual ~Derived2() = default;
        void run() {}
};
void doSomething(std::shared_ptr<Base> ptr) {
    ptr->run();
}
int main() {
    doSomething(std::make_shared<Derived1>());
    doSomething(std::make_shared<Derived2>());
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With