Это не недосмотр. Интересно, что в Decltype и auto (редакция 4) (N1705 = 04-0145) есть утверждение:
В правилах decltype теперь явно указывается, что decltype((e)) == decltype(e)
( как предложено EWG).
Но в Decltype (редакция 6): предлагаемая формулировка (N2115 = 06-018) одно из изменений
Заключенное в скобки выражение внутри decltype не считается id-expression
.
В формулировке нет никакого смысла, но я предполагаю, что это своего рода расширение decltype с использованием немного другого синтаксиса, другими словами, это было предназначено для дифференциации этих случаев.
Использование этого показано в C ++ draft9.2.8.4:
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17; // type is const int&&
decltype(i) x2; // type is int
decltype(a->x) x3; // type is double
decltype((a->x)) x4 = x3; // type is const double&
Что действительно интересно, так это то, как он работает с оператором return
:
decltype(auto) f()
{
int i{ 0 };
return (i);
}
Моя Visual Studio 2019 предлагает мне удалить лишние скобки, но на самом деле они превращаются в decltype((i))
, который меняет возвращаемое значение на int&
, что делает его UB, так как возвращение ссылки на локальную переменную.