Почему не удается сформировать ссылку на decltype (auto)

int main(){
    decltype(auto)&& a = 100;
}

Приведенный выше код, ошибка в GCC и Clang.

int main(){
    decltype(int)&& a = 100;
}

Этот код правильный.

In N4296,

В § 8.3.2 / 6

Если typedef (7.1.3), параметр шаблона типа (14.3.1) или спецификатор decltype (7.1.6.2) обозначают тип TR, который является ссылкой на тип T, попытка создать тип « Ссылка lvalue на cv TR »создает тип« ссылка lvalue на T », а попытка создать тип« ссылка rvalue на cv TR »создает тип TR.

спецификатор-декларации в § 7.1.6.2

спецификатор decltype:
decltype (выражение)
decltype (авто)

Я думаю, что в § 8.3.2 / 6 проблема с формулировкой.

Почему ссылка на decltype (auto) недопустима. Подскажите пожалуйста формулировку соответствующего стандарта. Извините за плохой английский. Спасибо.


person Cocoa    schedule 04.01.2015    source источник


Ответы (1)


В § 7.1.6.4 [dcl.spec.auto]

Если заполнитель является описателем типа decltype (auto), объявленный тип переменной или возвращаемый тип функции должен быть только заполнителем. Тип, выведенный для переменной или возвращаемого типа, определяется, как описано в 7.1.6.2, как если бы инициализатор был операндом decltype.

Итак, это разрешено:

decltype(auto) a = 100;

Но не это:

decltype(auto)& a = 100;

Или это :

decltype(auto)&& a = 100;

Это имеет смысл, поскольку одна из идей, лежащих в основе decltype(auto), состоит в том, чтобы сохранить ссылочность во время вывода типа (т. Е. Использовать вывод типа decltype вместо вывода шаблона / автоматического типа)


Стандарт дает нам примеры того, как decltype(auto) выводит ссылки:

int i;
int&& f();
auto x3a = i;                  // decltype(x3a) is int
decltype(auto) x3d = i;        // decltype(x3d) is int
auto x4a = (i);                // decltype(x4a) is int
decltype(auto) x4d = (i);      // decltype(x4d) is int&
auto x5a = f();                // decltype(x5a) is int
decltype(auto) x5d = f();      // decltype(x5d) is int&&
auto x6a = { 1, 2 };           // decltype(x6a) is std::initializer_list<int>
decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
auto *x7a = &i;                // decltype(x7a) is int*
decltype(auto)*x7d = &i;       // error, declared type is not plain decltype(auto)
person quantdev    schedule 04.01.2015
comment
Спасибо. §8.3.2 / 6 Сбивает с толку. - person Cocoa; 04.01.2015