Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't rvalue destroy right after it's used?

I wrote the following program and expected that the rvalue gotten from std::move() would be destroyed right after it's used in the function call:

struct A
{
    A(){ }
    A(const A&){ std::cout << "A&" << std::endl; }
    ~A(){ std::cout << "~A()" << std::endl; }
    A operator=(const A&){ std::cout << "operator=" << std::endl; return A();}
};

void foo(const A&&){ std::cout << "foo()" << std::endl; }

int main(){
    const A& a = A();
    foo(std::move(a)); //after evaluation the full-expression 
                       //rvalue should have been destroyed
    std::cout << "before ending the program" << std::endl;
}

But it was not. The following output was produced instead:

foo()
before ending the program
~A()

DEMO

As said in the answer

rvalues denote temporary objects which are destroyed at the next semicolon

What did I get wrong?

like image 839
user3663882 Avatar asked Sep 13 '25 12:09

user3663882


1 Answers

std::move does not make a into a temporary value. Rather it creates an rvalue reference to a, which is used in function foo. In this case std::move is not doing anything for you.

The point of std::move is that you can indicate that a move constructor should be used instead of a copy constructor, or that a function being called is free to modify the object in a destructive way. It doesn't automatically cause your object to be destructed.

So what std::move does here is that if it wanted to, the function foo could modify a in a destructive way (since it takes an rvalue reference as its argument). But a is still an lvalue. Only the reference is an rvalue.

There's a great reference here that explains rvalue references in detail, perhaps that will clear a few things up.

like image 73
rlbond Avatar answered Sep 15 '25 03:09

rlbond