【问题标题】:Why cannot I delete unique_ptr<char[]> with reset()?为什么我不能用 reset() 删除 unique_ptr<char[]>?
【发布时间】:2017-03-03 14:54:24
【问题描述】:

当我有一个指向单个对象的唯一指针时,我可以用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 '&lt;bound member function type&gt;'assigning to '&lt;bound member function type&gt;' 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);
    }

【问题讨论】:

  • 猜测编译器不兼容
  • coliru.stacked-crooked.com/a/0c14fa9b7a88e057 如我所料在 gcc 上运行良好,所以你的编译器一定有一些问题。也许尝试联系 C++ Builder 公司?
  • 使用 gcc (c++11) 编译器工作正常
  • _Enable_ctor_reset 看起来像某种std::enable_if:我很想看看背后的代码,但我猜它禁用了数组的reset
  • @wasthishelpful 我将其添加到问题中。

标签: c++ c++11 c++builder unique-ptr


【解决方案1】:

这似乎是标准库中的一个错误,因为相同的代码可以用其他编译器编译,正如 cmets 中的 deW1sanjay 所指出的那样。

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

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    相关资源
    最近更新 更多