Я не могу сделать это:
int &&q = 7;
int &&r = q;
//Error Message:
//cannot convert from 'int' to 'int &&'
//You cannot bind an lvalue to an rvalue reference
Если я правильно понимаю, при инициализации ссылки на rvalue есть инициализированная временная переменная. Так int &&q = 7;
можно рассматривать как:
int temp = 7;
int &&q = temp;
И при использовании ссылки на правой стороне, я на самом деле использую рефери. Так int &&r = q;
можно рассматривать как:
int &&r = temp; //bind an lvalue to an rvalue reference, cause error, understandable
Итак, выше, как я понимаю, возникает ошибка компилятора.
Зачем добавлять std::forward
может решить это?
int &&q = 7;
int &&r = std::forward<int>(q);
Я знаю std::forward
всегда возвращает ссылку на значение, как ссылка возвращается std::forward
отличный от int&&q
?
как ссылка возвращается
std::forward
отличный отint&&q
?
Их категории значений разные. И обратите внимание, что типы и категории значений — это разные вещи.
q
является именованной переменной, она квалифицируется как именующий, поэтому он не может быть привязан к rvalue ссылке.
(акцент мой)
имя переменной, функции, объекта параметра шаблона (начиная с C ++ 20) или члена данных, независимо от типа, такого как
std::cin
или жеstd::endl
, Даже если тип переменной является ссылкой на rvalue, выражение, состоящее из ее имени, является выражением lvalue;
В то время как ссылка rvalue, возвращаемая из функции, квалифицируется как xvalue, который принадлежит Rvalue.
вызов функции или перегруженное выражение оператора, тип возвращаемого значения которого является rvalue ссылкой на объект, такой как
std::move(x)
;
Разница между выражениями q
а также std::forward<int>(q)
является то, что первое является lvalue, в то время как второе является rvalue (фундаментальной категории xvalue).
Я обращался к аналогичным проблемам в этот ответ: Дело в том, что q
как выражение является именующий, потому что у него есть имя. std::forward<int>(q)
(или эквивалент std::move(q)
) являются выражениями, которые не имеют имен, и, поскольку они возвращают (неназванные) ссылки на rvalue, они являются значениями xvalue, которые являются подкатегорией rvalue и, таким образом, могут связываться со ссылкой на rvalue.