Ich verstehe die letzte Zeile des Beispiels auf Seite 148 der FCD (§7.6.1.2/4) nicht:
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = i; // type is const int&&
decltype(i) x2; // type is int
decltype(a->x) x3; // type is double
decltype((a->x)) x4 = x3; // type is const double&
Warum machen die Klammern hier einen Unterschied? Sollte es nicht einfach sein double wie in der Zeile oben?
Wenn e ein ungeklammerter id-Ausdruck oder ein Klassenmitgliedszugriff (5.2.5) ist, ist decltype(e) der Typ der Entität, die von e benannt wird.
wenn e ein lvalue ist, ist decltype(e) T&, wobei T der Typ von e ist;
Ich denke decltype(a->x) ist ein Beispiel für den “Klassenmitgliedszugriff” und decltype((a->x)) ist ein Beispiel für lvalue.
Aber das erklärt nicht die const 🙂
– fredoverflow
22. Juni 2010 um 23:11 Uhr
@FredOverflow: Tut auch: a Typ hat const A*
– Kubbi
22. Juni 2010 um 23:12 Uhr
“Klassenmitgliedszugriff” sollte “Klassendatenmitgliedszugriff” sein
– Camino
14. Dezember 2015 um 15:25 Uhr
James McNellis
decltype(a->x)
Dadurch erhalten Sie den Typ der Member-Variablen A::xwelches ist double.
decltype((a->x))
Dadurch erhalten Sie den Typ des Ausdrucks (a->x)was ein lvalue-Ausdruck ist (daher ist es eine const-Referenz–a ist ein const A*).
Okay, ich verstehe jetzt, wie die Regeln hier angewendet werden können, aber warum sind die Regeln so? Warum ist es sinnvoll zu unterscheiden a->x und (a->x)? Es kommt mir so willkürlich vor. Warum sollte ich jemals dieses Verhalten wollen? Irgendwelche Ideen?
– fredoverflow
23. Juni 2010 um 9:51 Uhr
Danke, aber beides decltype(f()) und decltype ((f())) Ertrag int auf meinem System. Habe ich dich falsch verstanden?
– fredoverflow
30. August 2010 um 19:21 Uhr
@Fred: Macht nichts. Ich habe mich geirrt. In diesem speziellen Fall werden die Klammern ignoriert, also sollten beide es sein const int.
– James McNellis
31. August 2010 um 2:17 Uhr
Gregor Domjan
Die hinzugefügten Klammern verwandeln es in einen lvalue.
Die inneren Klammern bewirken, dass die Anweisung als Ausdruck statt als Elementzugriff ausgewertet wird. Und da a als const-Zeiger deklariert ist, ist der Typ ein Verweis auf const double.
Rückverwiesen: quuxplusone.github.io/blog/2020/01/22/…
– alfC
8. März 2021 um 5:15 Uhr