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.