Search code examples
c++c++11shared-ptr

error when defining a std::shared_ptr with new operator


I am trying to define a std::shared_ptr with new operator in the following way:

#include <memory>

struct A {
};

int main() {

  std::shared_ptr<A> ptr = new A();

  return 0;
}

but I obtained the following compile-time error:

main.cpp: In function 'int main()':

main.cpp:8:30: error: conversion from 'A*' to non-scalar type 'std::shared_ptr' requested std::shared_ptr ptr = new A();

Anyway, the following definitely works:

      std::shared_ptr<A> ptr{new A()};

Does anyone of you know why this happens?


Solution

  • tl;dr: it's a consequence of the relevant constructor being explicit.

    When you initialise with =, you invoke copy-initialisation. C++ does not allow copy-initialisation of a shared_ptr from a raw pointer, because it would be too easy to end up with an accidental implicit conversion from some arbitrary raw pointer into a shared_ptr that doesn't actually manage it.

    This way, the only way you can "ensnare" a raw pointer into a shared_ptr is very deliberately and very explicitly (as you have correctly done in your second example). Now, only in this initialiser do you have to remember not to do so with a pointer you're already managing elsewhere.

    Is there anything actually dangerous about the specific line std::shared_ptr<A> ptr = new A()? No. But what you're seeing is a consequence of various C++ rules working together in concert.