我偶然发现了std::is_bounded_array
和std::is_unbounded_array
,我也知道std::make_unique
不支持有界数组。
有人能更清楚地解释为什么会这样吗?创建有界数组和创建无界数组有什么区别?
编辑:这与什么是无界数组?不同,因为这里提供的答案集中在无界数组上。这个问题更多地集中在实际和执行方面。创建有界数组与无界数组的不同方法是什么?为什么std::make_unique
不支持有界数组?从编译器的角度来看,有界数组和无界数组有什么不同?我能否将有界数组转换为无界数组,反之亦然?
发布于 2021-06-02 12:01:34
有界和无界数组是相关的一个奇怪的例子,这是C++中少数几种情况之一,在这种情况下,声明的对象类型与其他地方相同对象的声明类型不同。也就是说,当数组对象的(不完全)声明类型是未知绑定数组时,声明类型是已知绑定数组时。来自[basic.types]/6 矿场
类类型(如“class
X
”)在翻译单元中的某一点可能是不完整的,并在稍后完成;类型“类X
”在两个点上都是相同的类型。数组对象的声明类型可能是不完全类类型的数组,因此是不完整的;如果类类型稍后在转换单元中完成,则数组类型变得完整;这两点上的数组类型是相同的类型。数组对象的声明类型可能是未知绑定的数组,因此在翻译单元中的一点上是不完整的,并在稍后完成;在这两点上的数组类型(“T的未知界数组”和“N的数组”)是不同的类型。无法完成指向未知界限数组的指针类型,或由typedef声明定义为未知界限数组的类型的类型。[例子: // .arr[];// arr的类型是不完整的// .int arr10;//现在arr的类型是完全的
事实上,以下的计划是完善的:
#include <type_traits>
// declared type: array of unknown bound (and therefore incomplete)
extern int arr[];
static_assert(std::is_unbounded_array_v<decltype(arr)>);
static_assert(!std::is_bounded_array_v<decltype(arr)>);
// declared type: array of known bound (now the type of arr is complete)
int arr[10];
static_assert(!std::is_unbounded_array_v<decltype(arr)>);
static_assert(std::is_bounded_array_v<decltype(arr)>);
int main() {}
发布于 2021-06-02 12:27:32
在C++中,“无界数组”更正式地称为“未知界数组”,类似地,“有界数组”也称为“已知界数组”。
您不会创建一个未知绑定的数组对象。您可以通过新表达式创建不同边界的数组,并使用单个unique_ptr
来管理它们。
std::unique_ptr<int[]> p{new int[3]}; // p manages an array of size 3
p.reset(new int[4]); // now p manages an array of size 4
(在C++中,“数组绑定”和“数组大小”是同义词)。
提供了make_unique
,这样就不需要直接使用new
了。
auto p = std::make_unique<int[]>(3); // p manages an array of size 3
p = std::make_unique<int[]>(4); // now p manages an array of size 4
另一方面,您不需要有界数组的unique_ptr。只需定义数组:而不是std::unique_ptr<int[3]> pointer_to_array;
,而是使用int array[3]
。(实际上,std::unique_ptr<int[3]> p{new int[3]};
是畸形的。)因此,std::make_unique
不试图支持这种显然不存在的用例。
从编译器的角度来看,有界数组和无界数组有什么不同?
他们只是不同的类型。
我能否将有界数组转换为无界数组,反之亦然?
不和不。不存在对数组类型的隐式或显式转换。类型“已知绑定的数组”的表达式可以隐式转换为对未知绑定数组的引用,但是,由于P0388R4,指针转换是可能的。
https://stackoverflow.com/questions/67798458
复制相似问题