У меня есть код:
void f(int&& i) {
auto lambda = [](int&& j) { (void)j; }
lambda(i);
}
int main() {
f(5);
}
Clang ++ выдает ошибку: no known conversion from 'int' to 'int &&' for 1st argument
Почему i
меняет свой тип на int
когда передается в lambda()
?
Здесь работают два элемента:
i
имеет тип int&&
или «Rvalue ссылка на int
«, где» rvalue reference «- это имя для &&
функция, позволяющая связывание rvalues на ссылку;
i
имеет имя и поэтому выражение, называющее это именующий, независимо от его типа или того, что стандартный комитет решил назвать этот тип. 🙂(Обратите внимание, что выражение это выглядит как i
имеет тип int
не int&&
потому что причины. Значение r теряется, когда вы начинаете использовать параметр, если вы не используете что-то вроде std::move
чтобы вернуть его.)
i
имеет тип int&&
то есть это тип «rvalue ссылка на int
«Однако учтите, что i
сам это значение (потому что у него есть имя). И как lvalue, он не может связываться с «ссылкой на rvalue».
Чтобы связать это, вы должны превратить его обратно в значение, используя std::move()
или же std::forward()
,
Чтобы немного расширить: тип выражения и его категория значений являются (в значительной степени) независимыми понятиями. тип из i
является int&&
, категория стоимости из i
это значение.
i
это имя, и любой объект, к которому обращаются по имени, автоматически является LValue, даже если ваш параметр помечен как ссылка на rvalue. Вы можете разыграть i
вернуться к значению с помощью std::move
или же std::forward
void f(int&& i) {
auto lambda = [](int&& j) { (void)j; };
lambda(std::move(i));
}
int main() {
f(5);
}