Ссылка для пересылки по-прежнему является ссылкой или нет? - PullRequest
1 голос
/ 02 июля 2019

Я все еще смущен правилами, придуманными для поддержки перемещения и пересылки.Одна вещь, в которой я до сих пор не уверен:

Является ли ссылка для пересылки просто ссылкой на значение (с применением правил свертывания ссылок)?

Если это ссылка на rvalue, то почему функция:

template<typename T>
void func(T&&);

принимает не только rvalue, но и lvalue?

Ответы [ 2 ]

1 голос
/ 02 июля 2019

Я не уверен, удовлетворит ли вас этот ответ, но я могу указать на соответствующие части стандарта.В двух словах, ссылка 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.(Обратите внимание, что определение стандарта «ссылка на пересылку» на самом деле не требует вывода аргумента шаблона, хотя это основной способ, которым вы обычно хотели бы вызвать поведение свертывания ссылки.)

1 голос
/ 02 июля 2019

До замены T, T && является ссылкой на значение (очевидно).

После замены T (и после свертывания ссылок), T && либо остается ссылкой на значение (если T не является ссылкой) или становится ссылкой lvalue (если T является ссылкой lvalue).

...