I have a code:
void f(int&& i) {
auto lambda = [](int&& j) { (void)j; }
lambda(i);
}
int main() {
f(5);
}
Clang++ gives an error: no known conversion from 'int' to 'int &&' for 1st argument
Why the i
changes its type to int
when being passed to the lambda()
?
i
is of type int&&
, that is, it's of type "rvalue reference to int
." However, note that i
itself is an lvalue (because it has a name). And as an lvalue, it cannot bind to a "reference to rvalue."
To bind it, you must turn it back to an rvalue, using std::move()
or std::forward()
.
To expand a bit: the type of an expression and its value category are (largely) independent concepts. The type of i
is int&&
. The value category of i
is lvalue.
There are two elements at work here:
i
has type int&&
, or "rvalue reference to int
", where "rvalue reference" is the name for the &&
feature, allowing binding rvalues to a reference;i
has a name and so the expression naming it is an lvalue , regardless of its type or what the standard committee decided to call that type. :) (Note that the expression that looks like i
has type int
, not int&&
, because reasons. The rvalue ref is lost when you start to use the parameter, unless you use something like std::move
to get it back.)
i
is a name, and any object accessed by name is automatically an LValue, even though your parameter is marked as an rvalue reference. You can cast i
back to an rvalue by using std::move
or std::forward
void f(int&& i) {
auto lambda = [](int&& j) { (void)j; };
lambda(std::move(i));
}
int main() {
f(5);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.