Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a use case for std::unique_ptr<std::array<T,N>>

I came across something like:

using arr_t=std::array<std::array<std::array<int,1000>,1000>,1000>;
std::unique_ptr<arr_t> u_ptr;

The unique pointer was used, obviously, to overcome stackoverflow problem. Is there any case to use the previous code rather than just using std::vector ? Is there a real use case for std::unique_ptr<std::array<T,N>> ?

like image 718
Humam Helfawi Avatar asked May 03 '17 13:05

Humam Helfawi


People also ask

When should we use unique_ptr?

When to use unique_ptr? Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another.

What does unique_ptr get do?

unique_ptr::getReturns a pointer to the managed object or nullptr if no object is owned.

Can you pass a std :: unique_ptr as a parameter to a function?

You cannot do that because unique_ptr has a move constructor but not a copy constructor. According to the standard, when a move constructor is defined but a copy constructor is not defined, the copy constructor is deleted.

When should I use smart pointer?

It is useful for: Objects that must be allocated with new, but that you'd like to have the same lifetime as something on that stack. If the object is assigned to a smart pointer, then they will be deleted when the program exits that function/block.


1 Answers

The code above generates one contiguous buffer of a billion elements, with [] access that lets you get at elements as a 3-dimensional 1000-sided cube.

A vector of vectors of vectors would be a whole pile of non-contiguous buffers linked by pointers and ownership semantics.

I suspect you are suggesting

using u_ptr=std::vector<std::array<std::array<int,1000>,1000>>;

then resizing said arr_t to 1000 once created. This has the modest cost of an extra 2 pointer overhead in the handle object. It also permits varible size, which means that ensuring it is fixed size as intended is something the user code has to ensure. You'd want to block a pile of methods, basically everything unique_ptr doesn't expose, to ensure safety, or audit that your code doesn't use any of them.

Some of those operations could be very expensive; .push_back({}) would reallocate a gigabyte.

Now, maybe you intend you won't ever call that; but if you have generic code that processes vectors, you'd have to audit all of it to ensure that none of it every does these operations. It isn't possible to have a non-const handle to a vector that cannot resize it, for example, without rolling-your-own-span-class at this point.

We could block the methods we do not want to expose with private inheritance and using statements, but at this point we end up doing most of the work to get back to the unique_ptr solution.

like image 193
Yakk - Adam Nevraumont Avatar answered Sep 29 '22 06:09

Yakk - Adam Nevraumont