2017-11-27 1 views
0

In diesem Code:Klarstellung in Bezug auf Auto zu konstanten Referenz

int a=8; 
const int &b = a;   //b is a Low-Level const 
auto c = b; 

Ich erwartete c Konstante int-Typ sein, da es auto ed auf ein niedriges Niveau const war. Aber es bezieht sich auf a (die von b Aliasing) statt b für seine Erklärung.

c nimmt der b ‚s Art nur dann, wenn es wie auto &c =b

verwendet Was verstehe ich nur Top-Level-const fallen gelassen wird. Kann mir bitte jemand erklären, was mit meinem Verständnis nicht stimmt?

während im Falle eines Zeigers, der niedrige Pegel const von auto gerichtet:

int i=9; 
const int * p=&i; 
auto *d=p; 
*d=45; // error: assignment of read-only location ‘* d’ 

.

Antwort

3

Der Typ eines Ausdrucks ist niemals ein Referenztyp. Ausdrücke haben Nicht-Referenztypen und Wertkategorien.

Die Erklärung const int &b = a; Mittel:

  • Es wird eine Variable b genannt werden.
  • Der Ausdruck b hat den Typ const int.
  • Der Ausdruck b bezeichnet dasselbe Objekt wie a. Mit anderen Worten, die Namen a und b beziehen sich beide auf das gleiche Objekt.
  • Der Code decltype(b) wird in const int& aufgelöst, aber abgesehen davon können Sie nicht auf die "Geschichte" einer Referenz zugreifen. Sobald es gebunden ist, ist es nur ein Name für einen Int danach.

auto c = X; bedeutet, dass c nicht als Referenz deklariert ist; und sein Typ wird von dem Typ des Ausdrucks X abgeleitet. Wenn X zufällig der Bezeichner einer Variablen ist, ruft das KEINE speziellen Regeln auf; X wird in allen Fällen als Ausdruck behandelt.

Die Syntax decltype(auto) C = X; existiert; Wenn X der Name einer Variablen ist, bedeutet dies, dass C auf die gleiche Weise wie X deklariert ist.(Wenn X nicht der Name einer Variablen ist, hängt das Verhalten auch von der Wertkategorie von X ab). In Ihrem ersten Beispiel wird c vom Typ des Ausdrucks b abgeleitet, der const int ist. Wie Sie bereits angemerkt haben, wird die oberste Ebene const hier abgelegt, also auto c bedeutet int c.

In Ihrem zweiten Beispiel ist der Typ des Ausdrucks const int *. Dies ist keine oberste Ebene const, also auto d = p; wäre const int * d = p;. In diesem Fall unterscheidet sich auto *d nicht von auto d.

+0

So wird nur der Verweis aus dem Ausdruck nicht der Zeiger gelöscht, daher & mit Deklarator b angefügt ist, aber * mit p nicht angefügt ist nicht? –

+1

@AgrudgeAmicus Ein Zeigerdeklarator deklariert die Variable als Zeigertyp; Ein Referenzdeklarator deklariert die Variable so, dass sie den Zieltyp hat und dass sie initialisiert wird, indem sie an ein anderes Objekt bindet, das möglicherweise bereits existiert –

3

Auto verwendet die Regeln für den Vorlagentyp. Die lange und die kurze davon ist, dass Referenzen fallen gelassen werden, wenn Sie auto verwenden (was der Grund ist, dass Sie Dinge wie decltype(auto) als Rückgabe für Funktionen sehen, da dies einen anderen Satz von Regeln für den Typabzug verwendet).

Scott Meyers durchläuft die Regeln in Punkt 2 von Effective Modern C++.

0

In dem ersten Beispiel werden b und a verknüpft, aber c wird zur Konstante, dies ist wegen der const in b, die Wirkung. Das Problem mit dem zweiten Beispiel ist, dass * d der Typ const int ist, der nicht geändert werden kann.

Hoffe, das hilft.

Verwandte Themen