2016-11-15 5 views
6

Почему std :: tuple распадается на ссылки rvalue?Почему std :: tuple разлагаются на ссылки rvalue

#include <tuple> 

template <typename, typename> struct same_type; 
template <typename T> struct same_type<T, T> {}; 

void foo() { 
    std::tuple tuple(1, 'a', 2.3, true); 
    auto[i, c, d, b] = tuple; 
    same_type<decltype(i), int &&>{}; 
    same_type<decltype(c), char &&>{}; 
    same_type<decltype(d), double &&>{}; 
    same_type<decltype(b), bool &&>{}; 
} 

Это компилируется без ошибок, используя gcc trunk. Я бы предпочел, чтобы простые типы, например.

same_type<decltype(i), int>{}; 

Live example

ответ

9

GCC ошибка. decltype, применяемый к структурированному привязке, возвращает ссылочный тип, который для кортежного типа является точным типом, возвращаемым std::tuple_element. Другими словами, язык здесь довольно усложняется, чтобы скрыть тот факт, что на самом деле это ссылки.

[dcl.type.simple]/4:

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

  • , если e является заключённым в скобках ID выражения именования структурированного связывания ([ dcl.struct.bind]), decltype(e) является ссылочным типом, указанным в спецификации декларации структурированного связывания ;
  • [...]

[dcl.struct.bind]/3:

В противном случае, если выражение std::tuple_size<E>::value является хорошо образуют единое целое константное выражение [...] Учитывая тип Ti обозначенного по std::tuple_element<i, E>::type, каждый vi является переменной типа «ссылка на Ti», инициализируемой инициализатором, , где th e reference - ссылка lvalue, если инициализатор равен lvalue и rvalue reference иначе; ссылочный тип: Ti.

+3

Спасибо. Я снова открыл https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78358 – octoploid

Смежные вопросы