2016-11-15 4 views
6

Warum zerlegt std :: tuple in rvalue Referenzen?Warum zerlegt std :: tuple in rvalue Referenzen

#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 &&>{}; 
} 

Dies kompiliert ohne Fehler mit GCC-Trunk. Ich hätte stattdessen die einfachen Typen erwartet, z.B.

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

Live example

Antwort

9

GCC Fehler. decltype angewendet auf eine strukturierte Bindung gibt den referenzierten Typ zurück, der für den tupelartigen Fall der genaue Typ ist, der von std::tuple_element zurückgegeben wird. Mit anderen Worten, die Sprache versucht hier ziemlich hart, die Tatsache zu verbergen, dass diese tatsächlich Referenzen sind.

[dcl.type.simple]/4:

Für einen Ausdruck e, die durch decltype(e) bezeichneten Typ wie definiert ist folgende:

  • wenn e eine unparenthesized ID-expression eine strukturierte Bindungs ​​Benennung ([ dcl.struct.bind]), decltype(e) ist der referenzierte Typ, wie er in der Spezifikation der strukturierten Bindungsdeklaration angegeben ist ;
  • [...]

[dcl.struct.bind]/3:

Andernfalls, wenn der Ausdruck std::tuple_size<E>::value a wohlgeformter integraler konstanter Ausdruck [...] Angesichts die Art Ti bezeichnete durch std::tuple_element<i, E>::type ist jede vi eine Variable des Typs "Bezug auf Ti" initialisiert mit dem Initialisierer, wo th Die Referenz ist eine L-Wert-Referenz, wenn der Initialisierer ein Wert ist und andernfalls ein r-Wert; Der referenzierte Typ ist Ti.

+3

Danke. Ich habe https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78358 erneut geöffnet – octoploid

Verwandte Themen