What happens when you assign a literal constant to

2019-01-18 12:53发布

问题:

This is admittedly a nit-picky question that is mainly driven by curiosity. Suppose we have the following:

int x = 5;
int&& xref = std::move(x);
std::cout << "Before assignment x: " << x << std::endl;
std::cout << "Before assignment xref: " << xref << std::endl;
xref = 10;
std::cout << "After assignment x: " << x << std::endl;
std::cout << "After assignment xref: " << xref << std::endl;

The output as expected is:

// Before assignment x: 5
// Before assignment xref: 5
// After assignment x: 10
// After assignment xref: 10

This makes sense. std::move converts x to an xvalue and allows us to bind its memory location to xref and modify its contents accordingly. Now lets say we have the following:

int&& xref = 5;
std::cout << "Before assignment xref: " << xref << std::endl;
xref = 10;
std::cout << "After assignment xref: " << xref << std::endl;

int x = 5;
std::cout << "After assignment x: " << x << std::endl;

The output is intuitively:

// Before assignment xref: 5
// After assignment xref: 10
// After assignment x: 5

This make overall sense. We expect to be able to bind the constant literal 5 to xref because 5 is a prvalue. We also expect that xref be mutable. We further expect that the value of constant literal 5 isn't modifiable (as shown somewhat pedantically in the last two lines of the above snippet).

So my question is, what exactly is going on here? How does C++ know not to modify the value of the constant literal 5 yet maintain sufficient identity for xref to know that it's been changed to 10 by the assignment. Is a new variable being created upon assignment to xref when its bound to a constant literal? This question never came up in C++03 since only const references could be bound to rvalues.

回答1:

A temporary is constructed, initialised from the value of the literal, and it lasts as long as the reference. You can do what you like with this object.

In terms of lifetime, this is just the same as if you'd written const int& x = 5; only, there, the fact that you're working with an automatically-created temporary object is masked because the const prevents you from proving it with a mutation.

[C++14: 8.5.3/5]: [..] If T1 is a non-class type, a temporary of type “cv1 T1” is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary. [..]



回答2:

int&& xref = 5;

... creates a temporary, initialized with 5, whose lifetime is extended to the end of the block.

The assignment

xref = 10;

changes the value of the still living temporary.