0
votes

I am puzzled by the following code:

#include <iostream>

int main()
{
    int x{};

    int&& rvx = static_cast<int&&>(x);
    ++rvx;
    std::cout << x << std::endl;
}

The output of it is 1. I don't understand how this works. The static_cast is supposed to cast the lvalue x into an xvalue, which is then assigned to rvx. Why does incrementing rvx lead to a change in x? Is this because the converted lvalue-to-rvalue is essentially sitting at the same memory location, but it is just considered now a rvalue? I was under the impression (which is probably false) that somehow the cast creates a temporary out of its argument.

2
I think you are mixed up about what lvalue and rvalue means. Those are adjectives that describe an expression. They are not varieties of objects. - M.M
There is no internal state of an integer, besides it's value (There is nothing to move). - user2249683
@MattMcNabb I was a bit sloppy on my wording, I know that objects are always lvalues (as they are named), but as I said was under the impression that the static_cast makes a copy. - vsoftco
no, objects are not lvalues. They're objects. An lvalue is a category of expression. - M.M
@vsoftco An object is a region of memory. There's also some bits about an object's type, but the important part, it's a region of memory. There's no notion of how you access that memory. It may be through a variable, or it may be through any other expression. The result of a succesful call to malloc() points to an object, or to a sequence of objects, even though there is no variable referring to those objects. - user743382

2 Answers

5
votes

rvalue reference is a reference. In this, it works just like any other reference.

4
votes

An rvalue reference can bind to a temporary. This is what you'd get, for instance, if you write

int x{};
int&& rvx = +x;

But it doesn't need to bind to a temporary. By casting x to int&&, you've indicated to the compiler that that's okay too, that it may treat x as an rvalue to bind directly to the reference.