What are rvalues, lvalues, xvalues, glvalues, and prvalues? gives a good overview of the taxonomy of rvalues/lvalues, and one of the recent answers to that question (https:/
What is the true difference between an xvalue and a prvalue? The xvalue is a kind of rvalue that can be cv-qualified and refer to an object and have dynamic type equal or unequal the static type.
const int&& foo();
int&& _v=foo();
Without xvalue, the return value of the above function foo can only be a rvalue. But build-in types have not const rvalue! Thus, the above non-const variable _v can always bind the return value of foo(), even we wish the foo() return a const rvalue.
For polymorphic nonpod type xvalue expressions, the dynamic type of the expression is generally unknown at compile time (so a typeid expression on them is evaluated, and virtual function calls cannot in general be devirtualized).
For prvalues, that does not apply. The dynamic type equals the static type.
Another difference is that decltype(e)
is an rvalue reference type for xvalues and a non-reference type for prvalues.
Yet another difference is that an lvalue to rvalue conversion is not done for prvalues (they are already what the result would yield). This can be observed by some rather weird code
struct A {
int makeItANonPod;
A() = default;
private:
int andNonStdLayout;
A(A const&) = default;
};
void f(...);
int main() {
f(A()); // OK
f((A&&)A()); // illformed
}