Of course, this will not compile:
struct X {};
X&& x = X();
X&& x2 = x; // error: rvalue reference to type 'X' cannot bind to lvalue of type 'X'
Where is the relevant rule to this in the C++20 specification?
I read the section '9.4.3 References', but I cannot find the rule (I'm a novice on the C++ specification).
As a side note, I also cannot find the rule that permits the last line of the following (maybe finding it will help the main problem):
X x3;
X& x4 = x3;
X& x5 = x4;
As commented by François Andrieux and User17732522, the key point is interpreting the type of the initializer expression of a declaration.
The rule (5) of 9.4.3 says:
A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
When interpreting 'an expression of type T2', the rule (1) of 7.2.2 is applied:
If an expression initially has the type “reference to T” (9.3.3.2, 9.4.3), the type is adjusted to T prior to any further analysis. ...
So, when applying the rule (5) of 9.4.3 to the X&& x2 = x;
, T1 is X
and T2 is also X
. Because T1 and T2 are the same type, T1 is similar to T2 and T1 is reference-related to T2. This satisfies the condition of the rule (5.4.4) of 9.4.3, which says:
... - if the reference is an rvalue reference, the initializer expression shall not be an lvalue.
Therefore, the syntax does not permit X&& x = X(); X&& x2 = x;
because the initializer expression x
is an lvalue.
In the second example, the syntax permits X& x4 = x3; X& x5 = x4;
by applying the rule (5.1) of 9.4.3.