Why does calling std::move on a const
object call the copy constructor when passed to another object? Specifically, the code
The type of std::move(x)
is Foo const&&
which can't bind to Foo&&
. The reasoning is the same as for a T const&
not being able to bind to a T&
. You can, however, have a constructor taking a Foo const&&
. Most likely you won't be able to really move the corresponding object's data but, e.g., in your example there no data, i.e., the following code works OK:
#include <iostream>
struct Foo {
Foo() = default;
Foo(Foo &&) { std::cout << "Move\n"; }
Foo(Foo const&&) { std::cout << "Move const\n"; }
Foo(Foo const &) = delete;
};
int main() {
Foo const x; Foo y(std::move(x));
}
The type of the result of calling std::move
with a T const
argument is T const&&
, which cannot bind to a T&&
parameter. The next best match is your copy constructor, which is deleted, hence the error.
Explicitly delete
ing a function doesn't mean it is not available for overload resolution, but that if it is indeed the most viable candidate selected by overload resolution, then it's a compiler error.
The result makes sense because a move construction is an operation that steals resources from the source object, thus mutating it, so you shouldn't be able to do that to a const
object simply by calling std::move
.