When I have an 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 an std::unique_ptr
containing an array. Why? What is the proper way to delete such pointer?
I am using Embarcadero C++ Builder 10.1. and the relevant standard is C++11.
When I have an unique pointer containing an array, this fails to compile:
std::unique_ptr<char[]> variable(new char[10]);
variable.reset();
Error message is no matching function to call for 'reset'
.
This also fails:
std::unique_ptr<char[]> variable(new char[10]);
variable.reset(nullptr);
Error messages are 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;
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);
}
It seems that this is a bug in the standard library, because the same code compiles with other compilers, as pointed out by deW1 and sanjay in comments.
C++11 standard, section 20.7.1.3 ("unique_ptr for array objects with a runtime length") lists reset()
with the following signature:
void reset(pointer p = pointer()) noexcept;
The first example fails to compile, because the default argument is missing from the standard library implementation. The second example essentially calls reset(pointer())
, which fails to compile. Possibly this compile error is the reason why the default argument has not been added.
I have made a bug report to Embarcadero:
RSP-16165 Compile error when calling reset() on unique_ptr containing array object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With