2017-06-22 14 views
26

Rozważmy przykład:Czy decltype (auto) dla powiązania strukturalnego ma być referencją?

#include <iostream> 
#include <type_traits> 
#include <tuple> 

int main() { 
    auto tup = std::make_tuple(1, 2); 
    auto [ a, b ] = tup; 
    decltype(auto) e = a; 
    std::cout << std::boolalpha << std::is_reference_v<decltype(e)> << std::endl; 
} 

clang (Wydajność: false) i gcc (Wydajność: true) są zgadzając w tym najprostszym przypadku. Mając na uwadze np. this Q&As Czy numer e powinien być odnośnikiem, czy jest to błąd w gcc? A może kod jest źle sformułowany?

Odpowiedz

17

Identyfikatory same to referencje. Od [dcl.struct.bind]/3:

Biorąc pod uwagę typ T i wyznaczony przez std​::​tuple_­element<i, E>​::​type, każdego v i to zmienna typu „odniesieniem do T i” zainicjowany z inicjatora, gdzie odwołanie jest lwartością odniesienia jeśli inicjalizator jest wartością l-wartości i wartością rwartacji; typem odniesienia jest T i.

Oznacza to, a i b są zarówno int&&.

Ale sposób decltype(auto) faktycznie zachowuje pochodzi z [dcl.type.auto.deduct]:

Jeżeli zastępczy jest typu specifier decltype(auto), T będzie sam zastępczy. Typ wydedukowany dla T jest określony jak opisano w [dcl.type.simple], jak gdyby e był operandem decltype.

Sformułowanie to jest bardzo niewygodne, ale ostatecznie:

decltype(auto) e = a; 
~~~~~~~~~~~~~~ 

oznacza:

decltype(a ) e = a; 
     ~~~~ 

i decltype(a) środki, od [dcl.type.simple]/4.1:

jeśli e jest unparenthesized id-expression nazywanie powiązania strukturalnego ([dcl.struct.bind]), decltype(e) jest o typie referencyjnym podanym w specyfikacji deklaracji powiązania strukturalnego;

odwołuje typ z a jest int, więc e musi być int. Co oznacza, że ​​nie jest odniesieniem, a klang jest poprawny. Zapisano 81176.