https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120561
Bug ID: 120561 Summary: std::weak_ptr<T[N]> cannot be converted to std::weak_ptr<T[]> or std::weak_ptr<void>, and std::weak_ptr<T[]> cannot be converted to std::weak_ptr<void> Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: leekillough at gmail dot com Target Milestone: --- std::weak_ptr<T[N]> cannot be converted to std::weak_ptr<T[ ]>. std::weak_ptr<T[N]> cannot be converted to std::weak_ptr<void>. std::weak_ptr<T[ ]> cannot be converted to std::weak_ptr<void>. #include<memory> std::weak_ptr<int[1]> p1; std::weak_ptr<int[ ]> p2; std::weak_ptr<int[ ]> w1 = p1; std::weak_ptr<void > w2 = p1; std::weak_ptr<void > w3 = p2; Spurious errors occur in std::weak_ptr<T>::lock() trying to nothrow-construct std::shared_ptr<element_type> from std::weak_ptr<T> when T is an array, even though std::weak_ptr<T>::lock() is not needed for std::weak_ptr<T> construction. > /usr/include/c++/13/bits/shared_ptr_base.h:2068:16: error: no matching > function for call to ‘std::__shared_ptr<int, > > __gnu_cxx::_S_atomic>::__shared_ptr(const std::__weak_ptr<int [], > __gnu_cxx::_S_atomic>&, const std::nothrow_t&)’ > 2068 | { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); } > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prior to C++17, element_type = T. In C++17 and later, element_type = std::remove_extent_t<T>. When converting from std::weak_ptr<T> to std::weak_ptr<U> where T is array and T != U, std::weak_ptr<T>::lock() tries to nothrow-construct std::shared_ptr<element_type> from std::weak_ptr<T>. It is exactly the error produced by the code: #include<memory> template<class T> struct weak_ptr : std::weak_ptr<T> { auto lock() { return std::shared_ptr<typename std::weak_ptr<T>::element_type>(*this); } }; template struct weak_ptr<int[ ]>; template struct weak_ptr<int[1]>; It seems like a pre-C++17 implementation of std::weak_ptr<T>::lock() which assumes that element_type = T, is triggered by std::weak_ptr<T>::weak_ptr(const std::weak_ptr<U>&) when T is an array and T != U. These errors do not occur when converting from std::shared_ptr<T> to std::weak_ptr<U> where T is an array and T != U, and std::weak_ptr<T>::lock() otherwise works when T is an array. This occurs on almost all versions except trunk, but I cannot see this reported or confirmed fixed. Recording this in case others find the same error.