Saurav Yadav
Saurav Yadav

Reputation: 115

bounded arrays vs unbounded arrays in C++

I stumbled upon std::is_bounded_array and std::is_unbounded_array, and I also know that std::make_unique doesn't support bounded arrays.

Can someone shed more light into why that is so and what are the differences between creating a bounded array vs creating an unbounded array?

EDIT: This is different from what is an unbounded array? because the answers provided there are focused towards unbounded array. This question is more focused more on practical and implementation aspects. What are the different ways one can create a bounded array vs an unbounded array? Why does std::make_unique not support bounded arrays? For the standpoint of compiler, what all is different between a bounded array and an unbounded one? Can I cast a bounded array to unbounded array and vice-versa?

Upvotes: 1

Views: 1753

Answers (2)

cpplearner
cpplearner

Reputation: 15908

In C++, "unbounded array" is more formally known as "array of unknown bound", and similarly, "bounded array" is also called "array of known bound".

You don't create an array object of unknown bound. You can create arrays of different bounds via new-expressions, and use a single unique_ptr to manage them.

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

(In C++, "array bound" and "array size" are synonyms.)

make_unique is provided so that you don't need to directly use 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

On the other hand, you never need an unique_ptr of bounded array. You just define the array: instead of std::unique_ptr<int[3]> pointer_to_array;, you use int array[3]. (Actually, std::unique_ptr<int[3]> p{new int[3]}; is ill-formed.) So std::make_unique does not attempt to support such apparently nonexistent use case.

For the standpoint of compiler, what all is different between a bounded array and an unbounded one?

They are just different types.

Can I cast a bounded array to unbounded array and vice-versa?

No and no. There's neither implicit nor explicit conversion to array type. An expression of type "array of known bound" can be implicitly converted to a reference to array of unknown bound, and pointer conversion is possible, though, thanks to P0388R4.

Upvotes: 1

dfrib
dfrib

Reputation: 73186

A curious case where bounded vs unbounded arrays arrays is relevant is one of the few cases in C++ where the declared type of an object differs from the declared type of the same object elsewhere. Namely, when the (incomplete) declared type of an array object is an array of unknown bound vs. when the declared type is an array of known bound. From [basic.types]/6 [emphasis mine]:

A class type (such as “class X”) might be incomplete at one point in a translation unit and complete later on; the type “class X” is the same type at both points. The declared type of an array object might be an array of incomplete class type and therefore incomplete; if the class type is completed later on in the translation unit, the array type becomes complete; the array type at those two points is the same type. The declared type of an array object might be an array of unknown bound and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points (“array of unknown bound of T” and “array of N T”) are different types. The type of a pointer to array of unknown bound, or of a type defined by a typedef declaration to be an array of unknown bound, cannot be completed. [ Example:

// ...

extern int arr[]; // the type of arr is incomplete

// ...

int arr[10]; // now the type of arr is complete

And indeed, the following program is well-formed:

#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() {}

Upvotes: 3

Related Questions