Почему я не могу передать rvalue-ссылку, как это делается для другой функции в C++11?
У меня есть код:
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()
?
3 ответа
Здесь работают два элемента:
- Тип: параметр
i
имеет типint&&
или "Rvalue ссылка наint
", где"rvalue reference"- это имя для&&
функция, позволяющая привязывать значения к ссылке; - Значение категории: это ключ.
i
имеет имя, и поэтому выражение, называющее его, является lvalue, независимо от его типа или того, что стандартный комитет решил назвать этим типом.:)
(Обратите внимание, что выражение, которое выглядит как i
имеет тип int
не int&&
потому что причины. Значение r теряется, когда вы начинаете использовать параметр, если вы не используете что-то вроде std::move
чтобы вернуть его.)
i
имеет тип int&&
то есть это тип "rvalue ссылка на int
"Однако учтите, что i
сам по себе является lvalue (потому что у него есть имя). И как 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);
}