f(T&& arg)
Здесь T&& это универсальная ссылка
А тут
template <typename T>
struct S
{
void f(T&& arg) // это уже rvalue ссылка
}
В чем тут логика, почему во втором случае это не универсальная ссылка?
Потому что во втором случае при вызове f, класс уже должен быть инстанцирован некоторым конкретным T и не будет выводиться из arg во время вызова
И да, >> void f(T&& arg) // это уже rvalue ссылка Это ошибочный вывод, сжатие ссылок никуда не делось
Не соберётся этот пример без явного std::move и приведения в рвалуе
Советую проверять свои суждения перед ответом :) https://godbolt.org/z/8G3Y51jbq
Благодарю за подсказку, все равно это странно
T&& - универсальная ссылка, когда она непосредственно выводимая. В случае struct T уже выведено и является непосредственно каким то конкретным типом. Поэтому уже не универсальная, а конкретная.
ПС. Когда видите конструкцию template<typename T> somewhat(T&&). Думайте об это НЕ "я декларирую T&&", Это некоторая "конструкция языка T&&", которая становится типом, которым ее инициализировали.
Это просто ссылка, которая сожмётся при выводе аргумента (в обоих случаях), никакой магической конструкции в обоих случаях нет, как и нет особых правил, отличающих их друг от друга
Она сначала "конструкция", которая получает свой тип по правилу сжатия ссылок. Кстати прикольно раздумывать над auto&& x = -somewhat-
С auto&& то же самое же.
Во втором случае просто T в рамках структуры это уже конкретный тип. Поэтому и T&& приобретает более конкретное значение.
ну это если ты вместо компилятора подставил тип) по идее с помощью ctad можно компилятор заставить его выводить, как и для функции
Обсуждают сегодня