Std :: move calls the copy operator if used as an argument in the &&?
Here is my code:
#include <iostream>
class carl{
public:
int x;
carl(int y):x(y){
}
carl(carl&& other)
{
std::cout<<" cons called?"<<std::endl;
this->x = other.x;
other.x = 0;
}
void operator=(carl&& other){
std::cout<<"operator called?"<<std::endl;
this->x = other.x;
other.x = 0;
}
};
void funct(carl&& get){
std::cout<<get.x<<std::endl;
}
int main(int argc, char** argv) {
carl c(2);
funct(std::move(c));
std::cout<<c.x<<std::endl;
return 0;
}
Output:
2 2
If I remember, there is a special rule for special member functions that if a class has declared a constructor / move operator, then that class will not automatically generate copy operators / constructors.
Based on my example, it seems that the move operators and constructors were not called, but rather copied the value. It was supposed to release the value of c ' x
and confirm cout
, but none of this happened. Can anyone please explain what is going on with my code?
source to share
There are no moves happening in your code. func
takes a link as a parameter, so the transfer std::move(c)
just binds the link - no copy or move occurs. The key fact is that it std::move
doesn't move, it just returns an rvalue denoting an object. If you took your parameter by value:
void func(carl get);
Then you will create a new object that is initialized with the move constructor (if you pass the rvalue to func
).
source to share
For your example, here,
void funct(carl&& get) { std::cout<<get.x<<std::endl; }
gives exactly the same behavior as
void funct(carl& get) { std::cout<<get.x<<std::endl; }
Namely: you are passing a reference to the function.
Things only change when the rvalue reference is moved to a new object:
void funct(carl&& get)
{
auto my_carl = std::move(get);
std::cout<<my_carl.x<<std::endl;
}
The compiler then calls the move constructor carl
to move the content out of the object instead of making a copy.
source to share