为什么xvalues不能绑定到非const lvalue引用?
以下内容无法编译:
#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;
}
我很清楚为什么prvalues(未命名的临时对象)不绑定到非const lvalue引用-修改它们是没有意义的,因为它们很快就会消失.但是为什么xvalues不绑定到非const lvalue引用?
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?
如果函数返回 int&&
,则引用的对象不能是临时的,否则我们将获得悬挂的引用.因此,根据我的理解,如果返回 int&
,则该引用具有附加保证,可以安全地从中移出.
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.
纠正了措辞:值"绑定到引用",反之亦然.
Wording corrected: "Values" bind to "references" and not vice versa.
第二以下编译-除了y现在是左值之外,我没有看到概念上的区别.但是它仍然引用x.我了解根据语言规范,为什么应该编译而上面的代码不应该编译.但是,我不了解其背后的原因.为什么单纯的锯齿会改变图片?
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());
还允许
int && f() { ... }
int g (int & y) { ...}
int & k (int && y) { return y; }
g(k(f()));
因为这会造成混乱.
非 std :: move
—专门用于创建引用的新类",其绑定表示引用对象最有可能安全"地移出.
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.
如果这些引用对象也能够绑定到简单的 T&
,那么您将会遇到许多模棱两可的转换错误,而且没人会知道该怎么做.您可以将此类转化的排名降低,但是我仍然认为这仍然非常令人困惑.
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.
因此,您正在向后看.问问自己为什么 xvalues不绑定到非常量左值引用.
As such, you're looking at it backwards. Ask yourself instead why xvalues don't bind to non-const lvalue references.