2014-12-18 8 views
23

Myślę (myślę) Rozumiem auto. To samo dotyczy decltype. Jednak w C++ 14 można mieć pewne diaboliczne rzeczy jak decltype(auto) jako typ zwracany przez funkcję. Rozważmy następujący:Dlaczego decltype (auto) zwraca referencję tutaj?

decltype(auto) foo() 
{ 
    int m = 1; 
    return m; 
} 

Typ zwracany jest int, wszystko ma sens.

Jednakże

decltype(auto) foo() 
{ 
    int m = 1; 
    return (m); 
} 

powraca int& (to odniesienie do int).

Nie mam absolutnie żadnego pomysłu, dlaczego tak się dzieje, dlaczego te nawiasy mają jakąkolwiek różnicę !? Mam nadzieję, że ktoś może rzucić trochę światła na to.

PS: Oznaczono również tagiem C++, ponieważ jest o wiele więcej osób, które sprawdzają tag C++ niż C++14.

+2

Ponieważ 'decltype ((m))' jest także wartością odniesienia l. – 0x499602D2

+0

Tak myślałem, więc umieszczenie nawiasów wokół sprawia, że ​​jest to lwartość? Oznacza to, że jeśli zrobię "return (Foo())", jest uważany za zwracający odwołanie do 'Foo()'? – vsoftco

+1

@vsoftco nie, reguły dla 'decltype (e)' zależą od tego, czy 'e' jest nawiasie, czy też nie. Nie oznacza to, że dodawanie nawiasów gdzie indziej ma tego rodzaju efekt. –

Odpowiedz

28

7.1.6.2 [dcl.type.simple]

  1. do wyrażenia E, typ oznaczona decltype (e) jest zdefiniowana następująco:
    - jeśli e jest nieprecyzyjnym id-expression lub unpreathesized dostęp do klasy (5.2.5), decltype (e) jest typem podmiotu nazwanego przez e. Jeśli nie ma takiego bytu lub jeśli podaje zestaw nadmiernie obciążonych funkcji, program jest źle sformułowany;
    - w przeciwnym razie, jeśli e jest wartością x, typem decyzji (e) jest T & &, gdzie T jest typem e;
    - w przeciwnym wypadku, jeśli e jest lwartością, decltype (e) to T &, gdzie T jest typem e;
    - w przeciwnym razie, decltype (e) jest typem e.

W przykładzie masz return (m) tak e jest (m). To nie jest nieprecyzyjna identyfikacja wyrażeń lub dostęp do członków klasy, więc przechodzimy do drugiego punktu. To nie jest wartość x, więc idziemy do trzeciej kuli. Jest to wartość l, więc typ to T&, gdzie T jest .

+1

na miejscu, jedyne, czego nie dostaję, to dlaczego umieszczenie '(...)' sprawia, że ​​'decltype' uważa, że ​​ma lwartość – vsoftco

+4

' m' jest już lwartością, a '(m)' jest także lwartością . Chodzi o to, że nawiasy zmieniają sposób, w jaki 'decltype' pozwala wydedukować typ.Bez podwójnych nawiasów otrzymujesz po prostu rodzaj 'm', z podwójnymi nawiasami masz T && lub T i zależy od tego, czy' m' jest lwartością czy rwartością (w twoim przykładzie jest to lwartość) –

+0

Tego nie dostaję : pierwsza linia w twojej odpowiedzi: "jeśli e jest nieprosthedized ..." oznacza 'decltype (m)' deduces 'int'. Trzecia linia, "jeśli e jest lwartością ...", oznacza "int &". Jednak w pierwszym przypadku "e" (lub "m" w moim przypadku) jest również lwartością, ale ponieważ nie ma nawiasów, jest wydedukowane jako niereferencyjne? Muszę powiedzieć, że standard jest trochę zagmatwany, ale czy to się dzieje? – vsoftco

Powiązane problemy