【发布时间】:2013-05-11 21:47:33
【问题描述】:
始终使用命名空间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]()).p>
template <class T, class... Args> unspecified make_unique(Args&&...) = delete;5 备注:除非
T是一个已知边界的数组,否则该函数不参与重载解析。
现在,在我看来,这就像泥巴一样清晰,我认为它需要更多的阐述。但是,除了这篇社论评论,我相信我已经解码了每个变体的含义:
-
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);非数组类型的沼泽标准
make_unique。据推测,“备注”表示某种形式的静态断言或 SFINAE 技巧是为了防止在T是数组类型时成功实例化模板。在高层次上,将其视为等同于
T* ptr = new T(args);的智能指针。 -
template <class T> unique_ptr<T> make_unique(size_t n);数组类型的变体。创建一个动态分配的
n×Ts数组,并将其包装在unique_ptr<T[]>中返回。在高层次上,将其视为等同于
T* ptr = new T[n];的智能指针。 -
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]>?
【问题讨论】:
-
"这个函数应该不参与重载决议除非T是不是一个数组。" - 是的...
-
我认为答案是here
-
@Mehrdad:不是草案,而是新标准……
-
@Mehrdad:我同意!幸运的是,您的建议很容易遵循,因为到目前为止还没有人这样做。
-
而不是
T[N]* ptr = new (keep_the_dimension_please) (the_dimension_is_constexpr) T[N],您将使用不太符合的代码:T (*ptr)[N] = reinterpret_cast<T(*)[N]>(new T[N]);不符合是因为,尽管有一条特殊规则说您可以将指针转换为第一个元素从标准布局结构到指向结构的指针,数组没有类似的规则。但是,此代码可跨实际实现移植。
标签: c++ language-lawyer unique-ptr c++14