for a non-discarded return statement that occurs
in a function declared with a return type
that contains a placeholder type,
T is the declared return type
and E is the operand of the return statement.
If the return statement
has no operand,
then E is void();
for a non-type template parameter declared with a type
that contains a placeholder type,
T is the declared type of the non-type template parameter
and E is the corresponding template argument.
In the case of a return statement with no operand
or with an operand of type void,
T shall be either
type-constraintoptdecltype(auto) or
cvtype-constraintoptauto.
Obtain P from
T by replacing the occurrences of
type-constraintoptauto either with
a new invented type template parameter U or,
if the initialization is copy-list-initialization, with
std::initializer_list<U>.
If the deduction fails, the declaration is ill-formed.
Otherwise, T′ is obtained by
substituting the deduced U into P.
[Example 1: auto x1 ={1, 2}; // decltype(x1) is std::initializer_list<int>auto x2 ={1, 2.0}; // error: cannot deduce element typeauto x3{1, 2}; // error: not a single elementauto x4 ={3}; // decltype(x4) is std::initializer_list<int>auto x5{3}; // decltype(x5) is int — end example]
The type of i is the deduced type of the parameter u in
the call f(expr) of the following invented function template:
template<class U>void f(const U& u);
The type deduced for T is
determined as described in [dcl.type.decltype], as though
E had
been the operand of the decltype.
[Example 3: int i;
int&& f();
auto x2a(i); // decltype(x2a) is intdecltype(auto) x2d(i); // decltype(x2d) is intauto x3a = i; // decltype(x3a) is intdecltype(auto) x3d = i; // decltype(x3d) is intauto x4a =(i); // decltype(x4a) is intdecltype(auto) x4d =(i); // decltype(x4d) is int&auto x5a = f(); // decltype(x5a) is intdecltype(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 expressionauto*x7a =&i; // decltype(x7a) is int*decltype(auto)*x7d =&i; // error: declared type is not plain decltype(auto) — end example]