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?
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.
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