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?

+3


source to share


2 answers


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

).

+2


source


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.

+2


source







All Articles