问题
The following does not compile:
#include <iostream>
using namespace std;
int x = 5;
int && f () { return std::move(x); }
int g(int & y) { return y; }
int main() {
g(f());
return 0;
}
It's clear to me why prvalues (unnamed temporaries) do not bind to non-const lvalue references -- it does not make sense to modify them, as they will soon disappear. Yet why do xvalues not bind to non-const lvalue references?
If a function returns int &&
, the referenced object can't be temporary, otherwise we would get a dangling reference. Hence if an int &&
is returned, that's, in my understanding, a reference with the additional guarantee that it's safe to move from it.
Edit: Wording corrected: "Values" bind to "references" and not vice versa.
Second edit: The following compiles -- I do not see the conceptual difference, besides y now being an lvalue. Yet it still references x. I understand why this should compile and the above shouldn't, by the language specification. I do not, however, understand the reason behind it. Why does mere aliasing change the picture?
#include <iostream>
using namespace std;
int x = 5;
int && f () { return std::move(x); }
int g(int & y) { return y; }
int main() {
int && y = f(); // reference!
g(y); // compiles
// check that y indeed references x
y = 7;
std::cout << x << std::endl; // prints 7, of course
return 0;
}
Third edit: In short, what's the idea behind not allowing
int && f() { ... }
int g (int & y) { ...}
g(f());
yet allowing
int && f() { ... }
int g (int & y) { ...}
int & k (int && y) { return y; }
g(k(f()));
回答1:
Because that would make a mess.
The whole point of non-const
lvalue references is that they are aliases for non-temporary objects whose lifetime is already being managed by some other means. The introduction of rvalue references — and, crucially, std::move
— was specifically to create a new "class" of references whose binding signifies that the referent is most likely "safe" to move from.
If these referents also were able to bind to a simple T&
, you'd have a slew of ambiguous conversion errors and nobody would know what to do. You could give such conversions a lower rank, but I feel that this would still be extremely confusing.
As such, you're looking at it backwards. Ask yourself instead why xvalues don't bind to non-const lvalue references.
来源:https://stackoverflow.com/questions/34484246/why-dont-xvalues-bind-to-non-const-lvalue-references