【问题标题】:Why does std::unique_ptr need to be specialized for dynamic arrays?为什么 std::unique_ptr 需要专门用于动态数组?
【发布时间】:2026-02-23 01:05:01
【问题描述】:

我检查了 VC++ 2013 和 clang 3.4,发现两者都实现了std::unique_ptr,如下:

template<class T, class DeleterType = std::default_delete<T>>
class unique_ptr
{
    // ...
};

template<class T, class DeleterType>
class unique_ptr<T[], DeleterType>
{
    // ...
};

std::default_delete 能够判断 T 是否为数组类型。所以std::unique_ptr 不需要专门处理数组大小写。而且,我找不到class unique_ptr 和专门的class unique_ptr&lt;T[], DeleterType&gt; 之间的任何实质性区别,这是为什么呢?

【问题讨论】:

    标签: c++ visual-c++ c++11 clang template-specialization


    【解决方案1】:

    区别在于构造函数和reset() - unique_ptr&lt;T&gt; 接受任何可转换为T*X*,而unique_ptr&lt;T[]&gt; 只接受T*。考虑到数组的语义和限制,这是有道理的。

    另外,unique_ptr&lt;T[]&gt; 重载 operator[],而 unique_ptr&lt;T&gt; 不会。

    【讨论】:

    • unique_ptr的ctors接受T*作为它的参数,它是如何禁止类型转换的。比如说,A*可以转换为T*,调用unique_ptr(new A[1])?
    • @xmllmx 该标准有一条注释说“一种实现技术是创建这些成员的私有模板化重载。” See this recent question 正是为了这个讨论。哎呀,这是你自己的问题......所以,它已经回答了:-)
    • 删除器也不同——delete vs delete[]?
    • @Yakk 我相信这是std::default_delete的责任。
    • @angew 当然,但unique_ptr&lt;T&gt; 使用一个,而unique_ptr&lt;T[]&gt; 使用另一个默认删除器?