Why can't we initialize a reference to const int with rvalue volatile int &&?

I wrote the following example:

#include <iostream>

volatile int&& bar()
{
    return 1;
}

int main()
{
    const int& i = bar(); //error: binding of reference to type 'const int' 
                          //to a value of type 'volatile int' drops qualifiers
}

Demo

But if we replace int&&with int, it works fine:

#include <iostream>

volatile int bar()
{
    return 1;
}

int main()
{
    const int& i = bar(); //OK

}

Demo

which is not entirely clear. What the standard says ( 8.5.3/5 [dcl.init.ref]):

A reference to type "cv1 T1" is initialized by an expression of type "cv2 T2" as follows:

- If the link is an lvalue reference and an initialization expression

  • is an lvalue (but not a bitfield), and "cv1 T1" is link compatible with "cv2 T2" or

  • (.. T2 - ), T1 T2, lvalue "cv3 T3", "cv1 T1" - "cv3 T3" 108 ( (13.3.1.6) - (13.3)), lvalue lvalue (, , ).

[...]

- lvalue const (.. cv1 const), rvalue.

, rvalue volatile int&&. 'otherwise' . 5/5 [expr] :

" T" (8.3.2, 8.5.3), T .

, rvalue volatile int volatile int&&, , .

+3
1

, 1 2, (.. ; [dcl.init.ref]).

, T2 T1 ( T1 T2).

, , int , bar(), volatile. ( cv1 T1).


, Case 1 . -, bar() xvalue. . [basic.lval]/1 " , rvalue, xvalue".

[dcl.init.ref]/5:

  • lvalue [ lvalue] [ ]

: xvalue ( lvalue), , .

  • lvalue const (.. cv1 const), rvalue

: const int & lvalue const. :

  • - xvalue ( -), prvalue, prvalue lvalue "cv1 T1" "cv2 T2"
  • [ ]

[...]

, bar() x. x, , .


NB. ++ 14 (N3936). ++ 11 - DR1288.

+3

Source: https://habr.com/ru/post/1628176/


All Articles