Передача int && в f (int &&)
Что здесь происходит? Почему это ошибка?
void f(int &&);
int && i = 5;
f(i);
Разве это не слишком противоречиво?
Я бы ожидал, что i
будет ссылкой rvalue и поэтому сможет передать его f()
. Но я получаю сообщение об ошибке:
неизвестное преобразование от int
до int &&
Итак, я думаю, i
не является ссылкой на rvalue после объявления?
Ответы
Ответ 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));