37

This is the code from C++11 Notes Sample by Scott Meyers,

int x;
auto&& a1 = x;             // x is lvalue, so type of a1 is int&
auto&& a2 = std::move(x);  // std::move(x) is rvalue, so type of a2 is int&&

I am having trouble understanding auto&&.
I have some understanding of auto, from which I would say that auto& a1 = x should make type of a1 as int&

Which from Quoted code, seems wrong.

I wrote this small code, and ran under gcc.

#include <iostream>

using namespace std;

int main()
{
    int x = 4;
    auto& a1 = x;           //line 8
    cout << a1 << endl;
    ++a1;
    cout << x;
    return 0;
}

Output = 4 (newline) 5
Then I modified line 8 as auto&& a1 = x;, and ran. Same output.

My question : Is auto& equal to auto&&?
If they are different what does auto&& do?

Vinayak Garg
  • 6,518
  • 10
  • 53
  • 80
  • 4
    I think `auto&` and `auto&&` are equivalent if rhs is a lvalue. `auto&` will give you an error if rhs is an rvalue. – balki Feb 06 '12 at 15:52
  • [Lvalue references and rvalue references are similar](http://msdn.microsoft.com/en-us/library/f90831hc.aspx) – AJG85 Feb 06 '12 at 15:54
  • 4
    An `auto&&` variable means the same as a `T&&` parameter in a function template. – fredoverflow Feb 06 '12 at 17:13

1 Answers1

44

The code is right. auto&& p = expr means the type of p is T&& where T will be inferred from expr. The && here indicates a rvalue reference, so e.g.

auto&& p = 1;

will infer T == int and thus the type of p is int&&.

However, references can be collapsed according to the rule:

T& &   == T&
T& &&  == T&
T&& &  == T&
T&& && == T&&

(This feature is used to implement perfect forwarding in C++11.)

In the case

auto&& p = x;

as x is an lvalue, an rvalue reference cannot be bound to it, but if we infer T = int& then the type of p will become int& && = int&, which is an lvalue reference, which can be bound to x. Only in this case auto&& and auto& give the same result. These two are different though, e.g.

auto& p = std::move(x);

is incorrect because std::move(x) is an rvalue, and the lvalue reference cannot be bound to it.

Please read C++ Rvalue References Explained for a walk through.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005