xvalue 和 prvalue 之间的一些区别

Some differences between xvalue and prvalue

最近在认真研究C++的目录。左值和右值的区别似乎很清楚,但是当涉及到纯右值和无值时,我感到困惑。
给定以下示例:

#include <iostream>
using std::cout;
using std::endl;
using std::move;
class Type {
public:
    int value;
    Type(const int &value=0) :value(value) {}
    Type(const Type &type) :value(type.value){}
    Type(Type &&type) noexcept :value(type.value) {}
    Type &operator= (const Type &type) {
        value = type.value;
        return *this;
    }
    Type &operator=(Type &&type) noexcept{
        value = type.value;
        return *this;
    }
};
Type foo1(const Type &value) {
    return Type(value);
}
Type &&foo2(const Type &value) {
    return Type(value);
}
int main() {
    Type bar1(123);
    cout << foo1(bar1).value << endl;
    cout << foo2(bar1).value << endl;
    Type bar2;
    bar2 = foo1(bar1);
    cout << bar2.value << endl;
    bar2 = foo2(bar1);
    cout << bar2.value << endl;
    return 0;
}

运行 示例,控制台显示:
123
123
123
-858993460
谁能解释为什么它在最后的输出中给出了意外的值?
这个例子说明了 xvalue 的什么特征?

foo2 是 returning 引用绑定到立即销毁的临时;它总是 return 悬垂 reference

a temporary bound to a return value of a function in a return statement is not extended: it is destroyed immediately at the end of the return expression. Such function always returns a dangling reference.

取消对 returned 引用的引用,例如 foo2(bar1).valuebar2 = foo2(bar1); 会导致 UB;一切皆有可能。

另一方面,foo1没有这样的问题。 return 值从临时对象中移出。