C ++ Universal Reference и типовое выведение параметра LRef - PullRequest
1 голос
/ 18 марта 2019

Предположим, у нас есть код

template <typename T>
void Foo(T&& param);

int x = 5;
// deduced Foo<int&>(int&).
// Argument type A = int. T = int&.
Foo(x);     

int& rx = x;
// deduced Foo<int&>(int& &&) -> Foo<int&>(int&).
// But... argument type A = int&, an lvalue reference to int.
// Is T = int& or under the hood it is T = int& &?
Foo(rx);

Согласно https://en.cppreference.com/w/cpp/language/template_argument_deduction

4) Если P является rvalue-ссылкой на cv-неквалифицированный параметр шаблона (так называемая ссылка на переадресацию), а соответствующий аргумент вызова функции является lvalue, то для вывода A используется ссылка lvalue типа A вместо A

Что я хочу знать: правила «свертывания ссылок» применяются к выведенному типу T (не к P, типу параметра)?

Итак, действительно ли мы имеем для 'Foo (rx)' T = int & &, который свернулся до T = int &?

1 Ответ

3 голосов
/ 18 марта 2019

Обратите внимание, что практически во всех технических целях тип выражения никогда не считается ссылочным типом. [expr.type] / 1 :

Если выражение изначально имеет тип «ссылка на T» ([dcl.ref], [dcl.init.ref]), тип настраивается на T перед любым дальнейшим анализом.

Единственное заметное исключение - это когда decltype() применяется к непереносимому имени или выражению доступа к члену класса.Хотя синтаксис рассматривает имя как выражение, семантический результат включает в себя объявленный тип имени вместо тип и категория значения выражения.

Итак, в вашем примере, xlvalue типа int, а rx lvalue типа int.После их объявлений и инициализаций язык вообще не делает различий между ними, за исключением повторного использования decltype(x) или decltype(rx).

Это означает, что вычитание типа шаблона для Foo(rx) работает точно так же, какдля Foo(x): тип A равен int, а не int&, а аргумент является lvalue.По указанному вами правилу T выводится как int&, а при замене T=int& на тип функции правило свертывания ссылок говорит, что T&& равно int&.

...