28

What is the difference between

int a = 42;

and

int&& rvr = 42;

?

a is obviously an lvalue, but rvr is also an lvalue since it is a named variable, so can these expressions be considered exactly equivalent, and if not, in which scenarios the int&& declaration is preferred?

Wojtek
  • 801
  • 1
  • 9
  • 13

1 Answers1

25

They're not exactly equivalent. You're right that both variables are lvalues, but for most types, initialisation of the form

T a = b;

creates a temporary T object, and then constructs a from that temporary object. That temporary object may be elided, but it still requires the appropriate constructors to be available.

T &&a = b;

on the other hand, binds a directly to b, but requires b to be an rvalue. So:

int a = 3;
// int&&b = a; // error: && cannot bind to lvalues
int b = a; // okay

struct S { S(const S &) = delete; };
S f();
// S s = f(); // error: no copy or move constructor available
S&&s = f(); // okay

And more simply, decltype will also give different results for references.

  • The use of `[](auto&&x){ f(std::forward(x)); }` is a practical example of the use of `&&` and `decltype`. – Yakk - Adam Nevraumont Dec 22 '14 at 16:43
  • 1
    @Yakk Right, but that's C++14, not C++11. In C++11, `decltype` can be used the same way, but because lambda or function parameters cannot be declared `auto`, this particular pattern doesn't apply. –  Dec 22 '14 at 17:42
  • 1
    Could you explain what does S f(); do there? – Hai Bi Aug 26 '17 at 15:40
  • 1
    @HaiBi That's just a regular declaration of a function named `f` taking no parameters and returning `S`. –  Aug 26 '17 at 16:47
  • compared to int&& b = a, auto&& b = a is acceptable, auto&& here means a universal reference, deduced to int& – ZFY Mar 15 '20 at 03:23