为什么`make_unique <T [N]>`不允许?

Lig*_*ica 26 c++ unique-ptr language-lawyer c++14

std全程假设命名空间.

因此,C++ 14委员会草案N3690定义std::make_unique如下:

[n3690: 20.9.1.4]: unique_ptr创作    [unique.ptr.create]

template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);

1备注:除非T不是数组,否则此函数不应参与重载决策.
2返回:unique_ptr<T>(new T(std::forward<Args>(args)...)).

template <class T> unique_ptr<T> make_unique(size_t n);

3备注:除非T是未知范围的数组,否则此函数不应参与重载决策.
4返回:unique_ptr<T>(new typename remove_extent<T>::type[n]()).

template <class T, class... Args> unspecified make_unique(Args&&...) = delete;

5备注:除非T是已知绑定的数组,否则此函数不应参与重载决策.

现在,在我看来,这与泥浆一样清晰,我认为需要更多的阐述.但是,除了这篇评论之外,我相信我已经解释了每个变体的含义:

  1. template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);

    make_unique的非数组类型的标准.据推测,"注释"表示某种形式的静态断言或SFINAE技巧是为了防止模块在T数组类型时被成功实例化.

    在高级别,将其视为相当于的智能指针T* ptr = new T(args);.

  2. template <class T> unique_ptr<T> make_unique(size_t n);

    数组类型的变体.创建一个动态分配的数组n× Ts,并将其包装回一个unique_ptr<T[]>.

    在高级别,将其视为相当于的智能指针T* ptr = new T[n];.

  3. template <class T, class... Args> unspecified make_unique(Args&&...)

    不允许." 未指明 "可能是unique_ptr<T[N]>.

    否则智能指针会等同于无效的东西T[N]* ptr = new (keep_the_dimension_please) (the_dimension_is_constexpr) T[N];.

首先,我是对的吗?如果是这样,第三个功能发生了什么?

  • 如果不允许程序员在为每个元素提供构造函数参数的同时动态分配数组(尽可能new int[5](args)不可能),那么第一个函数无法为数组类型实例化的事实已经涵盖了这一点,不是吗?

  • 如果它是为了防止添加到像T[N]* ptr = new T[N](N某些地方constexpr)的构造的语言那么,那么,为什么呢?unique_ptr<T[N]>包含动态分配的N× Ts 块的存在不是完全可能的吗?这会是一件多么糟糕的事情,委员会已经不遗余力地禁止其创作make_unique

为什么不被make_unique<T[N]>禁止?

And*_*owl 33

引用原始提案:

T[N]

截至N3485,unique_ptr不提供部分专业化T[N].但是,用户会非常想写make_unique<T[N]>().这是一个不赢的场景.返回unique_ptr<T[N]>会选择单个对象的主要模板,这很奇怪.返回unique_ptr<T[]> 将是一个例外的是,否则铁定的规律 make_unique<something>()返回unique_ptr<something>.因此,此提议T[N]在此处形成错误,允许实现发出有用的static_assert消息.

该提案,斯蒂芬T. Lavavej,笔者说明了这种情况,这个视频核心C++(礼貌克里斯),从分钟1时01分10秒(或多或少)开始.

  • 顺便说一句:[直接链接到视频中的1:01:10](http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/STLCCSeries6#time=1h1m10s)(你可以调整URL的结尾) (3认同)