4

I fount the syntax got compile error.

std::shared_ptr<int> p = new int(5);

31 41 E:\temprory (delete it if u like)\1208.cpp [Error] conversion from 'int*' to non-scalar type 'std::shared_ptr<int>' requested

But it is O.K

std::shared_ptr<int> p(new int(5));

The same as unique_ptr;

But I don't know why it is prohibited.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
chang jc
  • 489
  • 8
  • 16

3 Answers3

12

The constructor of std::shared_ptr and std::unique_ptr taking raw pointer are explicit; std::shared_ptr<int> p = new int(5); is copy initialization, which doesn't consider explicit constructors.

Copy-initialization is less permissive than direct-initialization: explicit constructors are not converting constructors and are not considered for copy-initialization.

For direct initialization, explicit constructors are considered then std::shared_ptr<int> p(new int(5)); works fine.

Why the constructor is explicit?

To prevent unintentional implicit conversion and ownership transfer. e.g.

void foo(std::unique_ptr<int> p) { ... }

then

int* pi = new int(5);
foo(pi); // if implicit conversion is allowed, the ownership will be transfered to the parameter p
// then when get out of foo pi is destroyed, and can't be used again
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
5

C++ doesn't allow copy-initialisation of a shared_ptr from a raw pointer because shared_ptr 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.

msc
  • 33,420
  • 29
  • 119
  • 214
4

Imagine if you accidentally passed an int * pointer that you had to a function that took a std::shared_ptr<int>. When the function completed, the pointer would be freed. If you really want to transfer ownership, you should indicate so explicitly.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278