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

The above code, an error in the GCC and Clang.

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

This code correct.

In N4296,

In the § 8.3.2/6

If a typedef (7.1.3), a type template-parameter (14.3.1), or a decltype-specifier (7.1.6.2) denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type “lvalue reference to T”, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.

decltype-specifier in § 7.1.6.2

decltype-specifier:
  decltype ( expression )
  decltype ( auto )

I think § 8.3.2/6 is a problem with the wording.

Why reference to decltype(auto) is not allowed. Please tell me the wording of the relevant standard. Sorry in poor English. Thank you.

1

1 Answers

4
votes

In § 7.1.6.4 [dcl.spec.auto]

If the placeholder is the decltype(auto) type-specifier, the declared type of the variable or return type of the function shall be the placeholder alone. The type deduced for the variable or return type is determined as described in 7.1.6.2, as though the initializer had been the operand of the decltype.

So this is allowed :

decltype(auto) a = 100;

But not this:

decltype(auto)& a = 100;

Or this :

decltype(auto)&& a = 100;

This makes sense, since one of the idea behind decltype(auto) is to preserve reference-ness during type deduction (i.e. use decltype type deduction, instead of template/auto type deduction)


The standard gives us examples as how references are deduced by 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)