Почему я не могу передать 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);
}
Другие вопросы по тегам