Подтвердить что ты не робот

Передача int && в f (int &&)

Что здесь происходит? Почему это ошибка?

void f(int &&);

int && i = 5;

f(i);

Разве это не слишком противоречиво?

Я бы ожидал, что i будет ссылкой rvalue и поэтому сможет передать его f(). Но я получаю сообщение об ошибке:

неизвестное преобразование от int до int &&

Итак, я думаю, i не является ссылкой на rvalue после объявления?

4b9b3361

Ответ 1

Здесь существует основное различие между a и bind a. Например:

void f(int &&);

объявляет функцию, принимающую параметр, который может быть инициализирован только с помощью ссылки rvalue на тип (type convertible to) int.

int && i = 5;

объявляет значение lvalue, которое может быть инициализировано только с помощью ссылки rvalue на тип (type convertible to) int. Таким образом, в простых терминах

f(i);

пытается передать ссылку lvalue на int функции, принимающей только ссылки rvalue на int. Поэтому он не компилируется.

Чтобы передать компилятору значение lvalue в rvalue, используя, при необходимости, конструкторы перемещения (хотя и не в случае int), вы можете использовать std::move().

f(std::move(i));

Ответ 2

Я понимаю, почему вы в замешательстве. Следует помнить, что всякий раз, когда у вас есть имя переменной, у вас есть l-значение.

Итак, когда вы говорите:

int i = 0; // lvalue (has a name i)

А также

int&& i = 0; // lvalue (has a name i)

Так в чем же разница?

int&& может привязываться только к значению r, поэтому:

int n = 0;
int i = n; // legal

НО

int n = 0;
int&& i = n; // BAD!! n is not an r-value

Однако

int&& i = 5; // GOOD!! 5 is an r-value

Поэтому при передаче i в f() в этом примере вы передаете l-значение, а не r-значение:

void f(int &&);

int&& i = 5; // i is an l-value

f(i); // won't accept l-value

Ситуация на самом деле немного сложнее, чем я здесь. Если вас интересует более полное объяснение, то эта ссылка достаточно полная: http://en.cppreference.com/w/cpp/language/value_category

Ответ 3

Есть ли у него имя?
Является ли он адресуемым?

Если ответ на оба - "да", это значение L.

В этом фрагменте: i имеет имя, i имеет адрес (вы можете написать &i), поэтому это значение l.

f(&&) получает параметр r-value-reference в качестве параметра, поэтому вам нужно поменять значение l на значение r-value, которое можно сделать с помощью std::move.

f(std::move(i));