Obtain
P from
T by replacing the occurrence of
type-constraintopt auto either with
a new invented type template parameter U or,
if the initialization is copy-list-initialization, with
std::initializer_list<U>. If
E is a value synthesized for a constant template parameter
of type
decltype(auto) (
[temp.func.order]),
the declaration is ill-formed
. Otherwise, deduce a value for
U using the rules
of template argument deduction from a function call (
[temp.deduct.call]),
where
P is a
function template parameter type and
the corresponding argument is
E. 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 };
auto x2 = { 1, 2.0 };
auto x3{ 1, 2 };
auto x4 = { 3 };
auto x5{ 3 };
—
end example]
[
Example 2:
const auto &i = expr;
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);
—
end example]
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(auto) x2d(i);
auto x3a = i;
decltype(auto) x3d = i;
auto x4a = (i);
decltype(auto) x4d = (i);
auto x5a = f();
decltype(auto) x5d = f();
auto x6a = { 1, 2 };
decltype(auto) x6d = { 1, 2 };
auto *x7a = &i;
decltype(auto)*x7d = &i;
auto f1(int x) -> decltype(x)) { return (x); }
auto f2(int x) -> decltype(auto) { return (x); }
—
end example]