I have been carefully studying rvalues and rvalue references, in detail, for a number of weeks. I have growing confidence that I have some clarity in understanding the difference between:
- The type with which a variable or function parameter is defined (i.e.
int x;
vs.int && x = …;
- The expression category of expressions, including those that may use a previously defined parameter (i.e., given the function definition
A&& foo()
, and given an expression consisting solely offoo()
, the expression category is "xvalue") - The type of the result of evaluation of a subexpression when that expression is used within a containing expression (i.e., given the same definition of
foo
, the type of a subexpressionfoo()
when used within a containing expression isA
(notA&&
)).
My question regards the difference between xvalue expressions and prvalue expressions (both of these expression categories being rvalues).
Given:
class A
{};
A&& foo() {…}
A goo() {…}
void test(A&& a) {…}
int main()
{
test(foo()); // test() called with xvalue expression
test(goo()); // test() called with prvalue expression
}
Note that the function test()
is successfully called with both an xvalue expression, and a prvalue expression. (Please correct me if I have a misunderstanding about this.)
My question is: Since the function parameter A&& a
to test
successfully binds to both xvalues and to prvalues, what is the practical difference between xvalues and prvalues in terms of overload resolution?
Is there an example of a scenario in which the xvalue/prvalue nature of an expression results in different function overload resolution? Or is the distinction between xvalues and rvalues relevant only for other aspects of the language, independent of function overload resolution (for example, the result of decltype
(i.e., see What is decltype(0 + 0)?))?