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
What Can Make C++ Rtti Undesirable to Use
Is Is a Good Practice to Put the Definition of C++ Classes into the Header File
Template Type Deduction in C++ for Class VS Function
How to Use Signal Inside a C++ Class
Can't Downcast Because Class Is Not Polymorphic
What Does the "L" Mean at the End of an Integer Literal
Writing Python Bindings for C++ Code That Use Opencv
Why the Size of a Pointer to a Function Is Different from the Size of a Pointer to a Member Function
Access Violation on Static Initialization
How to Add the Mingw Bin Directory to My System Path
C++ Objects: When Should I Use Pointer or Reference
Why Doesn't C++ Have &&= or ||= for Booleans
"Apientry _Twinmain" and "Winapi Winmain" Difference
How to Tell If a Lib Was Compiled with /Mt or /Md