Is Std::Array Movable

Is std::array movable?

std::array is movable only if its contained objects are movable.

std::array is quite different from the other containers because the container object contains the storage, not just pointers into the heap. Moving a std::vector only copies some pointers, and the contained objects are none the wiser.

Yes, std::array uses the default move constructor and assignment operator. As an aggregate class, it's not allowed to define any constructors.

Understanding move semantics for std::array

I was expecting a sementation fault

First of all, most ways to get a segfault are as a result of undefined behaviour, in which case anything can happen and you probably shouldn't be expecting anything specific.

since v_ is supposed to be moved

A std::array contains its elements embedded directly inside it (not on the heap, referred to by a pointer, like a std::vector does) so you can't move its contents anywhere. They will always be inside it.

So all you've done is initialize a new array from the old one, you haven't moved anything. The elements of the new array will be initialized by rvalue doubles, but that doesn't move anything either, because you can't "move" a double (it has no externally-allocated data to transfer either). So it's just a copy of each element.

Move constructors and `std::array`

However, what does this really mean?

It means that, if the element type is movable, then so is the array type.

std::array<movable, 42> move_from = {...};
std::array<movable, 42> move_to = std::move(move_from); // moves all the elements

I tend to picture this type as a safer version of an array providing an STL-compliant interface

Not really. It's a wrapper for an array, giving it the same semantics as an aggregate class - including the ability to copy and move it.

how can an std::array move-construct its elements?

In exactly the same way as any other aggregate. Its implicit move-constructor will move-construct all its members, including the elements of any member arrays.

Can I do the same with an ordinary array?

Only if you wrap it in a class type, as std::array does.

C++ Move constructor for object with std::vector and std::array members

[...] and set the other's content to their default values?

No. When not stated otherwise a moved from object is in a valid, but unspecified state. Setting all elements to some default would be rather wasteful.

Further, a std::array does contain the elements. Its not just a pointer to some dynamically allocated elements that could cheaply be moved. The elements are right within the array. Hence you can only move the individual elements, the array as a whole can only be copied. A std::array is moveable when its elements are moveable, otherwise moving it will merely make a copy. For details I refer you to Is std::array movable?.

TL;DR

Vector(Vector&& other) = default; is fine. You just expected it do something it does not do. Neither does moving set the moved from elements to some default, nor does moving the std::array<size_t,2> actually move the elements, rather it copies them.



Related Topics



Leave a reply



Submit