-1

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;
relent95
  • 3,703
  • 1
  • 14
  • 17
  • 4
    See (5.4.4) in 9.4.3 in the linked document. – François Andrieux Aug 11 '23 at 13:39
  • 2
    "_As a side note, I also cannot find the rule that permits the last line of the following._": There is no extra rule needed. Both `x3` and `x4` are, as expressions, lvalues of type `X` with the identical result. So of course initialization `x4` and `x5` can't behave differently. – user17732522 Aug 11 '23 at 14:46
  • @François, (5.4.4) is under the condition "If T1 is reference-related to T2". Then ```X```(T1) is 'reference-related' to ```X&&```(T2)? But the (4) says "cv1 T1" is reference-related to "cv2 T2" if T1 is similar (7.3.5) to T2", and I can't find the rule determining ```X``` is similar to ```X&&``` in (7.3.5). – relent95 Aug 12 '23 at 00:36
  • @user17732522, you mean "(1) 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 ..." in the section "7.2.2 Type"? But that cannot be applied when interpreting the section "9.4.3 References", because it says "(5) A reference to type 'cv1 T1' is initialized ...", distinguishing a reference of a type and the type. (Of course I understand and agree your point, but I'm looking for the explicit rule. The question was tagged 'language-lawyer' by an editor.) – relent95 Aug 12 '23 at 00:44
  • 1
    @relent95 That section is under point 5 under the context of "A reference to type `cv1 T1` is initialized by an expression of type `cv2 T2` as follows:". In your case both `T1` and `T2` are `X`. A type is similar to itself (7.3.5) so `T1` is similar to `T2`. `T1` and `T2` are reference related if they are similar, so in your case they are reference related. – François Andrieux Aug 12 '23 at 01:13
  • 1
    @relent95 Yes, whether the id-expression refers to a variable of reference or non-reference type doesn't matter because of what you quoted. In 9.4.3. it doesn't say anything else. "A reference to type 'cv1 T1' is initialized" refers to the variable that is being initialized, not to the expression in its initializer. – user17732522 Aug 12 '23 at 06:34
  • @François and user17732522: Thanks for good explanations. Now I got it. If you don't mind, I'll answer my own question based on your comments. – relent95 Aug 12 '23 at 08:34
  • @relent95 You don't need to ask for permission. If anyone in the comments wanted to "stake claim" to this answer, they would have posted an answer already. And even if they change their mind, they can still choose to post a second answer. – François Andrieux Aug 12 '23 at 13:04

1 Answers1

1

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.

relent95
  • 3,703
  • 1
  • 14
  • 17