为什么 make_unique<T[N]>() 非法,而 make_shared<T[N]>() 合法?

问题描述 投票:0回答:1

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

c++ stl c++20 shared-ptr unique-ptr
1个回答
0
投票

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 风格的数组很愚蠢。

© www.soinside.com 2019 - 2024. All rights reserved.