auto[ x, y ]= f(); // x and y refer to elements in a copy of the array return valueauto&[ xr, yr ]= f(); // xr and yr refer to elements in the array referred to by f's return value
names a complete type,
the expression std::tuple_size<E>::value
shall be a well-formed integral constant expression
the number of elements in
the identifier-list shall be equal to the value of that
Let i be an index prvalue of type std::size_t
corresponding to vi.
The unqualified-idget is looked up
in the scope of E by class member access lookup ([basic.lookup.classref]),
and if that finds at least one declaration
that is a function template whose first template parameter
is a non-type parameter,
the initializer is
Otherwise, the initializer is get<i>(e),
where get is looked up in the associated namespaces ([basic.lookup.argdep]).
In either case, e is an lvalue if the type of the entity e
is an lvalue reference and an xvalue otherwise.
Given the type Ti
designated by std::tuple_element<i, E>::type,
variables are introduced with unique names ri
of type “reference to Ti”
initialized with the initializer ([dcl.init.ref]),
where the reference is an lvalue reference if the initializer is
an lvalue and an rvalue reference otherwise.
Each vi is the name of an lvalue of type Ti
that refers to the object bound to ri;
the referenced type is Ti.
all of E's non-static data members
shall be direct members of E or
of the same base class of E,
well-formed when named as e.name
in the context of the structured binding,
E shall not have an anonymous union member, and
the number of elements in the identifier-list shall be
equal to the number of non-static data members of E.
Designating the non-static data members of E as
m0, m1, m2,…
(in declaration order),
each vi is the
name of an lvalue that refers to the member mi of e and
whose type is cvTi, where Ti is the declared type of
that member; the referenced type is cvTi.
The lvalue is a
bit-field if that member is a bit-field.