为什么我不能用 reset() 删除 unique_ptr<char[]>?
Why cannot I delete unique_ptr<char[]> with reset()?
当我有一个指向单个对象的唯一指针时,我可以使用 reset()
:
删除它
std::unique_ptr<char> variable(new char);
variable.reset();
但是,这不适用于包含数组的 std::unique_ptr
。为什么?删除此类指针的正确方法是什么?
我正在使用 Embarcadero C++ Builder 10.1。相关标准是C++11.
我的观察
当我有一个包含数组的唯一指针时,编译失败:
std::unique_ptr<char[]> variable(new char[10]);
variable.reset();
错误信息是no matching function to call for 'reset'
。
这也失败了:
std::unique_ptr<char[]> variable(new char[10]);
variable.reset(nullptr);
错误消息是 cannot initialize a variable of type 'pointer' (aka 'char *') with an lvalue of type '<bound member function type>'
和 assigning to '<bound member function type>' from incompatible type '_Null_ptr_type' (aka 'nullptr_t')
。
这样编译:
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);
}
这似乎是标准库中的一个错误,因为相同的代码可以与其他编译器一起编译,正如 deW1 and sanjay 在评论中指出的那样。
C++11 标准,第 20.7.1.3 节 ("unique_ptr for array objects with a runtime length") 列出 reset()
具有以下签名:
void reset(pointer p = pointer()) noexcept;
第一个示例编译失败,因为标准库实现中缺少默认参数。第二个示例本质上调用了 reset(pointer())
,它无法编译。可能这个编译错误是没有添加默认参数的原因。
我已向 Embarcadero 提交错误报告:
RSP-16165 Compile error when calling reset() on unique_ptr containing array object
当我有一个指向单个对象的唯一指针时,我可以使用 reset()
:
std::unique_ptr<char> variable(new char);
variable.reset();
但是,这不适用于包含数组的 std::unique_ptr
。为什么?删除此类指针的正确方法是什么?
我正在使用 Embarcadero C++ Builder 10.1。相关标准是C++11.
我的观察
当我有一个包含数组的唯一指针时,编译失败:
std::unique_ptr<char[]> variable(new char[10]);
variable.reset();
错误信息是no matching function to call for 'reset'
。
这也失败了:
std::unique_ptr<char[]> variable(new char[10]);
variable.reset(nullptr);
错误消息是 cannot initialize a variable of type 'pointer' (aka 'char *') with an lvalue of type '<bound member function type>'
和 assigning to '<bound member function type>' from incompatible type '_Null_ptr_type' (aka 'nullptr_t')
。
这样编译:
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);
}
这似乎是标准库中的一个错误,因为相同的代码可以与其他编译器一起编译,正如 deW1 and sanjay 在评论中指出的那样。
C++11 标准,第 20.7.1.3 节 ("unique_ptr for array objects with a runtime length") 列出 reset()
具有以下签名:
void reset(pointer p = pointer()) noexcept;
第一个示例编译失败,因为标准库实现中缺少默认参数。第二个示例本质上调用了 reset(pointer())
,它无法编译。可能这个编译错误是没有添加默认参数的原因。
我已向 Embarcadero 提交错误报告:
RSP-16165 Compile error when calling reset() on unique_ptr containing array object