I have the following typedef:
using int_ref = int&&;
Why does the following code not produce an error (or print false
)?
std::cout << is_same< int_ref, int_ref&& >::value; // prints 1
I would expect that int_ref&&
gets expanded to int&& &&
which is obviously not possible. Am I missing something?
Rvalue references allow programmers to avoid logically unnecessary copying and to provide perfect forwarding functions. They are primarily meant to aid in the design of higer performance and more robust libraries.
Whatever has a name is an lvalue(1). So bar is an lvalue. Its type is "rvalue reference to string ", but it's an lvalue of that type. If you want to treat it as an rvalue, you need to apply std::move() to it.
In the example, the main function passes an rvalue to f . The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g ). You can cast an lvalue to an rvalue reference.
rvalue references have two properties that are useful: rvalue references extend the lifespan of the temporary object to which they are assigned. Non-const rvalue references allow you to modify the rvalue.
This is due to reference collapsing rules.
Basically, although you can't write a reference to a reference yourself, in some cases (typedefs, template parameters, decltypes) you can add create a reference to a reference type, which collapses as follows:
A& & -> A&
A& && -> A&
A&& & -> A&
A&& && -> A&&
In your case, int_ref
is int&&
, so int&& &&
becomes int&&
.
The relevant standard quote:
(N3337) [dcl.ref]/6:
If a typedef (7.1.3), a type template-parameter (14.3.1), or a decltype-specifier (7.1.6.2) denotes a typeTR
that is a reference to a typeT
, an attempt to create the type “lvalue reference to cvTR
”creates the type “lvalue reference toT
” , while an attempt to create the type “rvalue reference to cvTR
”creates the typeTR
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With