shared_ptr<T[N]>
的提案中有这样一段:
https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3920.html
unique_ptr 不幸失去了对 U[N] 的支持,这迫使我断言,在shared_ptr 的情况下,所述支持本质上是免费的,无论是在实现复杂性还是规范复杂性方面。请不要删除它。请考虑恢复 unique_ptr。
这只是“没有人建议恢复
unique_ptr<T[N]>
”的情况,还是有一些技术或向后兼容性原因导致无法完成?
我查看了这两个现有问题:
第一个问题是在
shared_ptr<T[N]>
之前写的,第二个问题考虑为什么添加了shared_ptr<T[N]>
而不是为什么它没有也添加到unique_ptr
。
std::make_unique<T[N]>
是非法的,因为删除者在这种情况下做了错误的事情。
std::default_delete<T[N]>
也没有针对固定大小数组的部分特化,因此它使用 delete
作为数组类型,这将是未定义的行为。
换句话说,
std::unique_ptr<T[N]>
几乎总是错误的,因为它缺少自定义删除器,并且std::make_unique<T[N]>
返回它是错误的。
最重要的是,也很难指定
std::make_unique
如何适用于数组。目前,[unique.ptr.create]指定:
unique_ptr<T>(new T(std::forward<Args>(args)...))
但是,这不适用于数组,因为
new T
其中 T = U[N]
产生 U*
,而不是 U(*)[N]
。
对于数组类型,这需要是:
unique_ptr<U[N]>(reinterpret_cast<U(*)[N]>(new U[N] {args...}));
但是,这在常量表达式中也不起作用,因为那里不允许使用
reinterpret_cast
。
即使来自 void*
的 C++26 constexpr 转换也无法解决这个问题。
总的来说,应该清楚支持
std::unique_ptr<U[N]>
和std::make_unique<U[N]>
并不是那么简单。
这也浪费了大家的时间,因为你可以直接使用 std::unique_ptr<std::array<U, N>>
来代替。
C 风格的数组很愚蠢。