Вчера видел интересный вопрос вот на ТАК про структурированную привязку.
Мы можем подвести итог следующим образом. Рассмотрим пример кода ниже:
#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 &
? Есть ли значимая причина, которую может понять профан?
decltype(x)
, гдеx
является структурированной привязкой, имена которой упоминаются
тип этого структурированного связывания. В случае с кортежем это
тип, возвращаемыйstd::tuple_element
, который не может быть ссылкой
даже если само структурированное связывание на самом деле всегда
ссылка в этом случае. Это эффективно имитирует поведение
привязка к структуре, чьи нестатические члены данных имеют типы
вернулсяtuple_element
со ссылкой на обязательный
Сам по себе является простой деталью реализации.
Эта тема была рассмотрена ранее (посмотрите в теге 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);