Подтвердить что ты не робот

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

Вчера я увидел интересный вопрос здесь о SO о структурированном привязке.
Мы можем подвести итог, как следует. Рассмотрим пример кода ниже:

#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 (возможно) из-за этой пули (рабочий проект):

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Если синтаксис будет расширен, чтобы позволить const/& -qualifying индивидуальный типы имен?

Например:

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);