Search code examples
c++shared-ptrreference-binding

Non-const lvalue reference to type 'A *' cannot bind to a value of unrelated type 'std::shared_ptr<A>'


First of all, there are bunch of similar posts which appear like they are exactly the same issue, but I find that they are different from my problem. I am trying to use smart pointers for the first time in my C++ life. I have trouble making polymorphism with smart pointers. To be precise I am trying to convert the following raw pointers (line # 15 of code shown below) to smart pointers:

class Maze {
 public:
  Maze() = default;
  ~Maze() = default;
  void BuildStack(MobileRobot *&robot_in_maze);
};

class Target {
 public:
  Target() = default;
  ~Target() = default;
  void GoWheeled();
 private:
  Maze wheeledMaze;
  MobileRobot *wheeledRobotInMaze = new WheeledRobot();
};

class MobileRobot {
 public:
  MobileRobot() = default;
  MobileRobot(std::string RobotName);
  ~MobileRobot() = default;
  std::string name;
};

class WheeledRobot : public MobileRobot {
 public:
  WheeledRobot(): MobileRobot("Wheeled Robot") {};
  ~WheeledRobot() = default;
};

class TrackedRobot : public MobileRobot {
 public:
  TrackedRobot(): MobileRobot("Tracked Robot") {};
  ~TrackedRobot() = default;
};

void Maze::BuildStack(MobileRobot *&robot_in_maze) {}

void Target::GoWheeled() {
     wheeledMaze.BuildStack(wheeledRobotInMaze);
}

When I try to convert line no 15 of code to a shared pointer type shown below :

std::shared_ptr<MobileRobot> wheeledRobotInMaze = std::make_shared<WheeledRobot>();

I get the following error at line no 41 of code:

Non-const lvalue reference to type 'MobileRobot *' cannot bind to a value of unrelated type 'std::shared_ptr<MobileRobot>'

Why is this happening ?


Solution

  • std::shared_ptr<X> is not implicitly convertible to X*. So since BuildStack expects a raw pointer, it complains when you try to call it with a shared_ptr. You can either just get the raw pointer from the shared_ptr:

    void Target::GoWheeled() {
         // this variable is only needed because BuildStack takes an lvalue reference
         // if you can change that, you don't need the variable
         MobileRobot* rawPtr = wheeledRobotInMaze.get();
         wheeledMaze.BuildStack(rawPtr);
    }
    

    Or, probably the better option since it's usually a good idea to consistently use shared_ptr instead of mixing it with raw pointers, you can change the signature of BuildStack to take a shared_ptr:

    void Maze::BuildStack(std::shared_ptr<MobileRobot> &robot_in_maze) {}