Why don't xvalues bind to non-const lvalue references?

。_饼干妹妹 提交于 2019-12-24 00:35:22

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!