структурированные привязки: когда что-то выглядит как ссылка и ведет себя аналогично ссылке, но это не ссылка

Вчера видел интересный вопрос вот на ТАК про структурированную привязку.
Мы можем подвести итог следующим образом. Рассмотрим пример кода ниже:

#include <tuple>
#include <type_traits>

int main() {
auto tup = std::make_tuple(1, 2);
auto & [ a, b ] = tup;
// the following line won't compile for a isn't a reference
// static_assert(std::is_reference_v<decltype(a)>);
}

В этом случае decltype(a) является int (вероятно) из-за эта пуля (рабочий проект):

если e это не заключенное в скобки id-выражение, обозначающее структурированную привязку […], decltype(e) ссылочный тип, указанный в спецификации объявления структурированной привязки

Вот фрагмент кода на wandbox, предоставленный @Curious в комментариях для тех, кто заинтересован. Это показывает, что на самом деле a не ссылка, не более того.
Пока что хорошо для первоначального вопроса, OP спросил, почему это было int вместо int & а также стандарт говорит, что выглядело как приемлемый ответ.

В любом случае, я хотел бы знать, почему комитет так решил. В конце дня, a относится к элементу в кортеже, и я могу изменить этот элемент через a, Другими словами, декларация a выглядит как ссылка, ведет себя аналогично ссылке, но это не ссылка.

Я могу жить с этим, но я хотел бы знать, каковы причины этого. Зачем decltype(a) не может быть просто int &? Есть ли значимая причина, которую может понять профан?

20

Решение

Я написал это вчера:

decltype(x), где x является структурированной привязкой, имена которой упоминаются
тип этого структурированного связывания. В случае с кортежем это
тип, возвращаемый std::tuple_element, который не может быть ссылкой
даже если само структурированное связывание на самом деле всегда
ссылка в этом случае. Это эффективно имитирует поведение
привязка к структуре, чьи нестатические члены данных имеют типы
вернулся tuple_elementсо ссылкой на обязательный
Сам по себе является простой деталью реализации.

10

Другие решения

Эта тема была рассмотрена ранее (посмотрите в теге structd-bindings), а поведение, о котором вы говорите, даже рассматривается во втором ответе. Тем не менее, обоснование изложено в p0144r2 раздел 3.5:

Должен ли синтаксис быть расширен для const/&квалифицирующее лицо
типы имен?

Например:

auto [&x, const y, const& z] = f(); // NOT proposed

Мы думаем, что ответ должен быть нет. Это простая функция для хранения
значение и привязать имена к его компонентам, чтобы не объявлять несколько
переменные. Разрешение такой квалификации будет ползучим,
расширение функции, чтобы быть чем-то другим, а именно способ
объявить несколько переменных.

Если мы хотим объявить несколько переменных, у нас уже есть способ
произнеси это по буквам:

 auto val    = f();
T& x        = get<0>(val);
T2 const y  = get<1>(val);
T3 const& z = get<2>(val);
-1

По вопросам рекламы [email protected]