Ответ 1
Это ошибка компилятора 78939. Хотя это немного сложнее, - было несколько проблем между основным языком и библиотекой, которые были взаимно противоречивыми (GB 20, LWG 2770 и LWG 2446), которые приводят к типу поведение, которое демонстрирует здесь gcc/libstdС++. Разумеется, предполагается, что код работает с или без #include <utility>
, это просто вопрос о том, что стандартная формулировка попала туда должным образом.
Да, классы со всеми общественными членами, не являющимися анонимными членами, должны использоваться в объявлениях структурированных привязок для [dcl.struct.bind]/4
В противном случае все члены нестатических данных
E
должны быть публичными прямыми членамиE
или одного и того же однозначного публичного базового классаE
,E
не должны иметь анонимного члена объединения, а количество элементов в списке идентификаторов должно быть равно числу нестатических элементов данныхE
. Обозначая нестатические элементы данныхE
как m0, m1, m2,... (в порядке объявления), каждое vi является именем lvalue, которое относится к члену mi e и тип которого cv Ti, где Ti - объявленный тип этого члена; ссылочный тип - cv Ti. Lvalue - это бит-поле, если этот элемент является битовым полем. [Пример:struct S { int x1 : 2; volatile double y1; }; S f(); const auto [ x, y ] = f();
Это полностью не связано с включением <utility>
, ничего в этом коде не зависит от какой-либо функциональности библиотеки - элементы захватываются напрямую, а не через механизм get
/tuple_size
.