First, I read this answer to realize that why we want to convert an unique_ptr to a shared_ptr sometimes. Then, I follow the instructions of the converting on cppreference shared_ptr.
In C++11 and C++14 it is valid to construct a std::shared_ptr<T> from a std::unique_ptr<T[]>:
std::unique_ptr<int[]> arr(new int[1]);
std::shared_ptr<int> ptr(std::move(arr));
Since the shared_ptr obtains its deleter (a std::default_delete<T[]> object) from the std::unique_ptr, the array will be correctly deallocated.
This is no longer allowed in C++17. Instead the array form std::shared_ptr<T[]> should be used.
So, I try it on Ubuntu and Windows respectively.
The following code can be built PASS on Ubuntu using g++ v11.4.0
g++ -std=c++17 ./test.cpp -o test_cpp
#include <memory>
int main()
{
std::unique_ptr<int[]> arr(new int[1]);
std::shared_ptr<int[]> ptr(std::move(arr));
return 0;
}
On the other hand, it shows the following error messages on Windows 11 using llvm-mingw g++ v12.0.0
.test.cpp:6:28: error: no matching constructor for initialization of 'std::shared_ptr<int []>'
std::shared_ptr<int[]> ptr(std::move(arr));
^ ~~~~~~~~~~~~~~
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2711:23: note: candidate constructor not viable: no known conversion from 'typename remove_reference<unique_ptr<int []> &>::type'
(aka 'std::unique_ptr<int []>') to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
_LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2725:5: note: candidate constructor not viable: no known conversion from 'typename remove_reference<unique_ptr<int []> &>::type'
(aka 'std::unique_ptr<int []>') to 'const std::shared_ptr<int []>' for 1st argument
shared_ptr(const shared_ptr& __r) _NOEXCEPT;
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2732:5: note: candidate constructor not viable: no known conversion from 'typename remove_reference<unique_ptr<int []> &>::type'
(aka 'std::unique_ptr<int []>') to 'std::shared_ptr<int []>' for 1st argument
shared_ptr(shared_ptr&& __r) _NOEXCEPT;
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2713:18: note: candidate template ignored: could not match '_Yp *' against 'typename remove_reference<unique_ptr<int []> &>::type'
(aka 'std::unique_ptr<int []>')
explicit shared_ptr(_Yp* __p,
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2728:9: note: candidate template ignored: could not match 'shared_ptr' against 'unique_ptr'
shared_ptr(const shared_ptr<_Yp>& __r,
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2733:52: note: candidate template ignored: could not match 'shared_ptr' against 'unique_ptr'
template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r,
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2736:34: note: candidate template ignored: could not match 'weak_ptr' against 'unique_ptr'
template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2744:9: note: candidate template ignored: requirement '!is_array<int []>::value' was not satisfied
[with _Yp = int [], _Dp = std::default_delete<int []>]
shared_ptr(unique_ptr<_Yp, _Dp>&&,
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2753:9: note: candidate template ignored: requirement 'is_lvalue_reference<std::default_delete<int []>>::value' was not satisfied
[with _Yp = int [], _Dp = std::default_delete<int []>]
shared_ptr(unique_ptr<_Yp, _Dp>&&,
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2709:23: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
_LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2721:26: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2723:51: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2716:9: note: candidate constructor template not viable: requires at least 2 arguments, but 1 was provided
shared_ptr(_Yp* __p, _Dp __d,
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2722:40: note: candidate constructor template not viable: requires 3 arguments, but 1 was provided
template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
^
C:localllvm-mingw-20210423-msvcrt-x86_64includec++v1memory:2719:9: note: candidate constructor template not viable: requires at least 3 arguments, but 1 was provided
shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
^
1 error generated.
So, my question is
- Is there anything wrong in my test code?
- Why are the results different among these two environments?
- How to make it work on Windows with llvm-mingw?
Any help and hint is appreciated.
Rock is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1