#include
struct A { int a[100]; };
void foo (const A& a) {
std::vector vA;
vA.push_back(std::move(a)); // how does move really happen
Created a snippet to show it. Though in your example default constructor will be called, but you get the idea.
#include <vector>
#include <iostream>
struct A {
int a[100];
A() {}
A(const A& other) {
std::cout << "copy" << std::endl;
}
A(A&& other) {
std::cout << "move" << std::endl;
}
};
void foo(const A& a) {
std::vector<A> vA;
vA.push_back(std::move(a));
}
void bar(A&& a) {
std::vector<A> vA;
vA.push_back(std::move(a));
}
int main () {
A a;
foo(a); // "copy"
bar(std::move(a)); // "move"
}
std::move
doesn't do a move. It actually casts the lvalue reference to an rvalue reference. In this case, the result of the move is a const A &&
(which is totally useless by the way).
std::vector
has an overload for a const A &
and a A &&
, so the overload with const A &
will get chosen and the const A &&
is implicitly casted to const A &
The fact that std::move
can be called on const objects, is strange/unexpected behavior for most programmers, though it somehow is allowed. (Most likely they had a use case of it, or none to prevent it)
More specific for your example, the move constructor of the class A will get called. As A is a POD, this most likely will just do a copy as all bits just have to move/copied to the new instance of A.
As the standard only specifies that the original object has to be in a valid though unspecified state, your compiler can keep the bits in A in place and doesn't have to reset them all to 0. Actually, most compilers will keep these bits in place, as changing them requires extra instructions, which is bad for performance.