问题
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]:
[..] IfT1
is a non-class type, a temporary of type “cv1T1
” 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.
来源:https://stackoverflow.com/questions/51985202/why-can-i-assign-value-to-rvalue-reference-which-refers-to-literals