Я не уверен, удовлетворит ли вас этот ответ, но я могу указать на соответствующие части стандарта.В двух словах, ссылка T&&
является «грамматически» всегда ссылкой rvalue, но иногда тип, который она объявляет, является типом ссылки lvalue.
Когда это происходит в результате вывода аргумента шаблона,Вся конструкция называется «ссылка на пересылку», как удобное сокращение.(Это обстоятельство требует свертывания ссылок, но вычитание аргументов шаблона - не единственный случай, когда происходит свертывание ссылок.)
Теперь перейдем к стандартной формулировке.Сначала мы имеем [dcl.ref] (например, p2 , p6 ):
Ссылочный тип, который объявлен с использованием &
, называется lvalue reference , а ссылочный тип, объявленный с использованием &&
, называется rvalue reference .[...]
Если typedef-name (9.1.3, 13.1) или decltype-спецификатор (9.1.7.2) обозначает тип TR
это ссылка на тип T
, попытка создать тип «lvalue ссылка на cv TR
» создает тип «lvalue ссылка на T
», а попытка создатьтип «rvalue ссылка на cv TR
» создает тип TR
.[ Примечание : это правило называется свертыванием ссылок.- конец примечания ]
Наконец, случай вывода аргумента шаблона обрабатывается в [temp.deduct.call] p3 :
A ссылка на пересылку - это r-значение ссылки на неквалифицированный cv параметр шаблона [...]
Другими словами, ссылка на пересылку - это ссылка на rvalue, но она также принимает lvalue.(Обратите внимание, что определение стандарта «ссылка на пересылку» на самом деле не требует вывода аргумента шаблона, хотя это основной способ, которым вы обычно хотели бы вызвать поведение свертывания ссылки.)