Why can't I remove unique_ptr <char []> with reset ()?
When I have a unique pointer to a single object, I can delete it with reset() :
std::unique_ptr<char> variable(new char); variable.reset(); However, this does not work for std::unique_ptr containing an array. What for? How can I remove such a pointer?
I am using Embarcadero C ++ Builder 10.1. and the corresponding standard is C ++ 11.
My observations
When I have a unique pointer containing an array, this will not compile:
std::unique_ptr<char[]> variable(new char[10]); variable.reset(); Error message no matching function to call for 'reset' .
This also fails:
std::unique_ptr<char[]> variable(new char[10]); variable.reset(nullptr); Error messages cannot initialize a variable of type 'pointer' (aka 'char *') with an lvalue of type '<bound member function type>' and assigning to '<bound member function type>' from incompatible type '_Null_ptr_type' (aka 'nullptr_t') .
This compiles:
std::unique_ptr<char[]> variable(new char[10]); variable = nullptr; Relevant code from <memory>
template<class _Uty> using _Enable_ctor_reset = enable_if_t< is_same<_Uty, pointer>::value || (is_same<pointer, element_type *>::value && is_pointer<_Uty>::value && is_convertible< remove_pointer_t<_Uty>(*)[], element_type(*)[] >::value)>; _Myt& operator=(_Null_ptr_type) _NOEXCEPT { // assign a null pointer reset(pointer()); return (*this); } _NOINLINE void reset(_Null_ptr_type _Ptr) _NOEXCEPT { // establish new null pointer pointer _Old = this->_Myptr; this->_Myptr = _Ptr; if (_Old != pointer()) this->get_deleter()(_Old); } template<class _Uty, class = _Enable_ctor_reset<_Uty> > void reset(_Uty _Ptr) _NOEXCEPT { // establish new pointer pointer _Old = get(); this->_Myptr() = _Ptr; if (_Old != pointer()) this->get_deleter()(_Old); } This seems to be a bug in the standard library, because the same code compiles with other compilers, as deW1 and sanjay pointed out in the comments.
C ++ 11 standard, section 20.7.1.3 ("unique_ptr for array objects with execution length") lists reset() with the following signature:
void reset (pointer p = pointer ()) noexcept;
The first example cannot be compiled because the default argument is missing in the standard library implementation. The second example essentially calls reset(pointer()) , which does not compile. This compilation error is probably the reason that the default argument was not added.
I made the error message Embarcadero:
RSP-16165 Compilation error when calling reset () on a unique array_ptr object