11 Declarators [dcl.decl]

11.5 Structured binding declarations [dcl.struct.bind]

Структурированная связывании декларация вводит identifiers v0, v1, v2, ... из identifier-listкак названия ([basic.scope.declarative]), называется structured bindingс. Позвольте cv обозначить cv-qualifiers в decl-specifier-seq. Сначала вводится переменная с уникальным именем e . Если assignment-expressionв initializer имеет тип массива, A а не ref-qualifierприсутствует, e имеет тип, cv A и каждый элемент инициализируется копией или инициализируется напрямую из соответствующего элемента, assignment-expressionкак указано в форме initializer. В противном случае e определяется как если бы

attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt e initializer ;

где объявление никогда не интерпретируется как объявление функции, а части объявления, кроме declarator-id, взяты из соответствующего объявления структурированной привязки. Тип id-expression e называется E. [ Note: E никогда не является ссылочным типом (пункт [expr]). ]end note

Если E это тип массива с типом элемента T, количество элементов в identifier-listдолжно быть равно количеству элементов E. Каждый vi - это имя lvalue, которое относится к элементу i массива и имеет тип T; ссылочный тип - T. [ Note: CV-квалификаторы верхнего уровня T are cv. ] [end noteExample:

  auto f() -> int(&)[2];
  auto [ x, y ] = f();          // x and y refer to elements in a copy of the array return value
  auto& [ xr, yr ] = f();       // xr and yr refer to elements in the array referred to by f's return value

end example]

В противном случае, если qualified-id std​::​tuple_­size<E> имена являются полным типом, выражение std​::​tuple_­size<E>​::​value должно быть правильно сформированным интегральным константным выражением, а количество элементов в identifier-listэлементе должно быть равно значению этого выражения. unqualified-id get Ищется в объеме E путем class member access lookup, и если , который находит по крайней мере , одна декларация, то инициализатор e.get<i>(). В противном случае инициализатор находится там get<i>(e), где get ищется в associated namespaces. В любом случае get<i> интерпретируется как template-id. [ Note: Обычный unqualified lookup не выполняется. ] В любом случае является lvalue, если тип объекта является ссылкой lvalue, и xvalue в противном случае. Принимая во внимание типа обозначен , каждый представляет собой переменную типа «ссылка на » инициализируется инициализатор, где ссылка является ссылкой , если именующим инициализатор является Левым и ссылкой на Rvalue в противном случае; ссылочный тип - .end note e e Ti std​::​tuple_­element<i, E>​::​type vi Ti Ti

В противном случае все Eнестатические элементы данных должны быть общедоступными прямыми членами одного E и того же однозначного общедоступного базового класса E, E не должны иметь анонимного члена объединения, а количество элементов в классе identifier-listдолжно быть равно количеству нестатических элементов. -статические данные членов E. Обозначая нестатические элементы данных , E как m0, m1, m2, ... (в порядке декларации), каждый vi является именем именующего , который относится к элементу mi из e и типа которого является cv Ti, где Ti находится объявленный тип этого члена; ссылочный тип - cv Ti. Lvalue является битовым полем, если этот член является битовым полем. [Example:

struct S { int x1 : 2; volatile double y1; };
S f();
const auto [ x, y ] = f();

Тип id-expression x - «const int», тип id-expression y - «const volatile double». ]end example