Talk:cpp/memory/shared ptr/shared ptr

The page says:

"When constructing a shared_ptr from a raw pointer to an object of a type derived from std::enable_shared_from_this, the constructors of shared_ptr detect other owners of the object through the weak reference stored in that base class. This allows ownership of the object to be shared with existing shared_ptrs. Otherwise, it is undefined behavior to construct a shared_ptr for an object that is already managed by another shared_ptr."

But this does not work in GCC. Is it in the C++ standard? Which paragraph?

--78.12.76.238 11:14, 3 February 2014 (PST)


 * This description follows §20.8.2.4[util.smartptr.enab]/11, which says "The shared_ptr constructors that create unique pointers can detect the presence of an enable_shared_from_this base and assign the newly created shared_ptr to its __weak_this member.". In LLVM libc++ this functionality is implemented by the call to __enable_weak_this from the shared_ptr's constructors. GNU libstdc++ makes a call to __enable_shared_from_this_helper from __shared_ptr's constructors. (note: this may have been worded poorly on this page, I'll review) --Cubbi (talk)
 * Yes, the description on this page was wrong, fixed. Thank you for bringing it up! --Cubbi (talk) 12:01, 3 February 2014 (PST)


 * Much better now. I made a small edit that makes wording even more explicit. I think that even a tiny misunderstanding of the role of std::enable_shared_from_this can bring to daunting bugs. Feel free to rollback my edit, though. --78.12.77.107 09:38, 4 February 2014 (PST)

The example on https://en.cppreference.com/w/cpp/memory/weak_ptr/owner_before shows a constructor in the form std::shared_ptr xx(std::shared_ptr)yy, &yy->n1) where n1 is an element of type int within Foo. Shouldn't constructor example (8) read: "template< class Y > shared_ptr( const shared_ptr& r, Y* ptr ) noexcept" ? Fneske (talk) 10:34, 27 September 2020 (PDT)
 * It's correct as is. In the expression std where decltype(p1) is std, is int,  is, and decltype(&p1->n1) is int*, which is std as required. --Ybab321 (talk) 02:30, 28 September 2020 (PDT)

aliasing c'tor with nullptr?
Can we clarify what happens if we pass `nullptr` as the second argument to the aliasing c'tor? It seems to Just Work, but in a very weird way: https://godbolt.org/z/sj6zP8 It puts things in a state where we have a `nullptr` that is keeping something alive. Is that guaranteed by the standard? BenFrantzDale (talk) 12:32, 10 December 2020 (PST)
 * It's valid. The shared_ptr instance is what's keeping something alive, though, not the nullptr that happens to sit in its other member. I suppose we could mention it, though it's two levels of obscurity down (level one being the existence of aliasing ctor itself and its intended use). I found one blog mentioning this (from "The other special case is where the stored object is NULL while the owned one is not.") --Cubbi (talk) 09:11, 11 December 2020 (PST)

Constructing a std::shared_ptr from a std::unique_ptr
The page says: "In C++11 and C++14 it is valid to construct a std::shared_ptr from a std::unique_ptr:"

However, the code snippet does not compile with g++: https://ideone.com/s6AHOv


 * seems it was applied as a defect, retroactively; you can get it to compile in gcc 6.2 and clang 3.2. And with modern clang, you can see it is checking that it's not an array even in C++11 mode: note "!is_array"
 * ... but then it builds again with trunk clang in C++17 mode, worth a closer look at why. --Cubbi (talk) 11:25, 5 September 2021 (PDT)