Moving can't be implemented efficiently (O(1)) on std::array, so why does it have move constructor ?
3 Answers
std::array has a compiler generated move constructor, which allows all the elements of one instance to be moved into another. This is handy if the elements are efficiently moveable or if they are only movable:
#include <array>
#include <iostream>
struct Foo
{
Foo()=default;
Foo(Foo&&)
{
std::cout << "Foo(Foo&&)\n";
}
Foo& operator=(Foo&&)
{
std::cout << "operator=(Foo&&)\n";
return *this;
}
};
int main()
{
std::array<Foo, 10> a;
std::array<Foo, 10> b = std::move(a);
}
So I would say std::array should have a move copy constructor, specially since it comes for free. Not to have one would require for it to be actively disabled, and I cannot see any benefit in that.
5 Comments
nothrow? Or can it simply leave the operation in any legal state?std::array move-constructor doesn't provide the strong exception safety guarantee. Only the basic one. See the first bullet of 12.8/15. My only doubt is if the "corrresponding subobject" is also an rvalue. What do you think?noexcept moveable, then the generated move constructor will be too. And if it isn't, then neither will the generated one be.To summarize and expand on other answers, array<T> should be moveable (when T itself is moveable) because:
Tmay be efficiently moveable.Tmay be move-only.
4 Comments
array<T> is movable (for movable T) makes sense.Have a look at the standard:
23.3.2.2 array constructors, copy, and assignment [array.cons]
The conditions for an aggregate (8.5.1) shall be met. Class array relies on the implicitly-declared special member functions (12.1, 12.4, and 12.8) to conform to the container requirements table in 23.2. In addition to the requirements specified in the container requirements table, the implicit move constructor and move assignment operator for array require that T be MoveConstructible or MoveAssignable, respectively.
The move constructor and assignment operator are by far not free, they may not be provided.
std::arraydoesn't have any constructors except the defaults generated by the compiler.std::arrayhas a move constructor)?O(1)move constructor". All instantiations ofstd::array<int, 5>take the same time to move/copy.std::array<int, 6>? That's a different type!