Тип привязки ссылки из std::tuple

Какой тип a Вот?

#include <iostream>
#include <tuple>

using namespace std;

int main()
{
    float x{};
    std::tuple<int> tpl( x );
    auto& [ a ] = tpl;
    static_assert( std::is_same_v< decltype( a ), int> );
    //static_assert( std::is_same_v< decltype( a ), int&> );
}

Согласно Стандарту 11.5 / 3:

[...] Учитывая тип Ti, обозначенный std::tuple_element<i, E>::typeпеременные вводятся с уникальными именами ri типа "ссылка на Ti", инициализированными инициализатором (11.6.3), где ссылка является ссылкой lvalue, если инициализатор является lvalue, и ссылкой rvalue в противном случае. Каждый vi - это имя l-типа типа Ti, которое относится к объекту, связанному с ri; ссылочный тип - Ti.

Вот, i 0 для первого элемента (int) и E является std::tuple<int>, так Ti имеет тип std::tuple_element<0, std::tuple<int>>::typeт.е. int, В дальнейшем ri (a в нашем случае) имеет тип "ссылка на Ti", т.е. int&, но не только int, Что не так в этой цитате и почему int тип выводится как компиляторами clang, так и gcc?

2 ответа

Решение

Это правда, что тип переменной r0 является int&, Но v0здесь называется a, это другая вещь, имя структурированной привязки, и технически вообще не является переменной, просто это другой тип имени.

Итак, нам нужно посмотреть на описание decltypeв [dcl.type.decltype]:

Для выражения eтип обозначен decltype(e) определяется следующим образом:

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

Так что здесь "ссылочный тип" просто int,

Конечно, decltype((a)) является int& как и следовало ожидать. decltype имя без двойных скобок используется для определения того, как имя "объявлено", а не как оно ведет себя, поэтому не очевидно, что decltype(a) "должен" быть одно или другое, так как a не имеет нормального объявления. Хотя это потенциально немного полезно, учитывая std::tuple<int, int&> t{0, n}; auto& [a, b] = t;, у нас есть decltype(a) является int но decltype(b) является int&,

Заметка

ссылочный тип - Ti.

Для структурированных привязок, decltype возвращает ссылочный тип ( [dcl.type.decltype]):

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

Другие вопросы по тегам