It’s not an oversight. It’s interesting, that in Decltype and auto (revision 4) (N1705=04-0145) there is a statement:
The decltype rules now explicitly state that
decltype((e)) == decltype(e)
(as suggested by EWG).
But in Decltype (revision 6): proposed wording (N2115=06-018) one of the changes is
Parenthesized-expression inside decltype is not considered to be an
id-expression
.
There is no rationale in the wording, but I suppose this is kind of extension of decltype using a bit different syntax, in other words, it was intended to differentiate these cases.
The usage for that is shown in 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&
What is really interesting, is how it works with the return
statement:
decltype(auto) f()
{
int i{ 0 };
return (i);
}
My Visual Studio 2019 suggest me to remove redundant parenthesis, but actually they turn into decltype((i))
which changes return value to int&
which makes it UB since returning reference to a local variable.