Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 388
FdeF Avatar asked Jan 05 '23 06:01

FdeF


1 Answers

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.

like image 53
Lightness Races in Orbit Avatar answered Jan 13 '23 11:01

Lightness Races in Orbit