2014-01-07 6 views
7
int v[1]; 
auto p1 = v; 
auto &p2 = v; 
auto *p3 = v; 

p1 ist vom Typ int * (gleich für p3). Insbesondere bei dieser trivialen Probe finde ich p2 (int (&)[1]) nützlicher, da es Array-Semantik, z. Ich kann sizeof auf p2 anwenden, um dasselbe wie sizeof auf v zu geben.Warum Typ-Abzug für Arrays priorisiert Zeiger auf den ersten Bezug auf Array?

Gibt es dafür ein Standardangebot?

Warum ist das Verwerfen von Referenzen eine schlechte Idee? (Für diesen Array-Fall meine ich, fast kein C++ - Programmierer interessiert sich heutzutage für sie ...)

+5

'Gibt es dafür ein Standardzitat?' 7.1.6.4/7 gibt an, dass die Regeln für den Typabzug mit 'auto' gleich sind (modulo' initializer_list') wie die Regeln für die Ableitung von Templateargumenten. 14.8.2.1/2 (für die Ableitung von Vorlagenargumenten) gibt dann an, dass der Abfall vom Array-Typ zum Zeigertyp nur für Nicht-Referenzparameter auftritt. –

+1

Es könnte auch interessant sein zu bemerken, dass das Gleiche für Funktionstypen gilt. Wenn Sie die Definition von 'v' in' void v() 'ändern, dann ist' p1' 'void (*)()', aber 'p2' ist' void (&)() ' – Praetorian

+0

C hat keine Referenzen , daher zerfallen Arrays in Zeiger, wenn sie als Funktionsargumente übergeben werden. C++ hat das Verhalten von C aus Gründen der Kompatibilität geerbt. – Casey

Antwort

2

Ich glaube, es ist für Konsistenz mit Nicht-Template-Funktionen. Arrays unterliegen bei jedem Zugriff der Konvertierung von Array zu Zeiger, außer wenn sie an eine Referenz gebunden sind. So mit den bestehenden Regeln sind folgende konsequent:

int v[1]; 

void foo(int *); 

int main() 
{ 
    foo(v); 
} 

und

int v[1]; 

template <class T> 
void foo(T); 

int main() 
{ 
    foo(v); 
} 
+0

Typ Abzug im Vorlagencode ist etwas ähnlich wie "Auto". Ich meine, ich könnte die gleiche Frage mit Vorlagen in einfachen C++ 98 =) tun.aber wie auch immer, ich kann Template-Argumente vorhersehen, die zu Array-Referenzen aufgelöst werden, wie es für Auto sein könnte, bleibt doch die Frage, wo das am schlimmsten ist? Ich kenne die Regel über das Verfallen von Arrays zu Zeigern, aber ich sehe nicht, dass es die Bindung an die Referenz über einen Zeigertyp ausschließt. Ich sehe, es gibt eine Konsistenz mit der Verfall zu Zeiger-Regel obwohl ... –

+0

@pepper_chico Typ Abzug für Vorlagen Code ist fast genau das gleiche wie "Auto" (anders herum, eigentlich); Deshalb habe ich eine Vorlage in der Antwort verwendet. Beachten Sie auch, dass dies der einzige Fall wäre, wenn ein Parameter, der kein lexikalisches '&' oder '&&' enthält, auf eine Referenz zurückgeführt werden kann - eine ziemlich hässliche Ausnahme, würde ich sagen. – Angew

4

auto folgern einen Nicht-Referenz-Typen.

auto& leitet eine Referenz ab.

auto const& leitet eine const Referenz.

auto&& leitet entweder eine Referenz, eine const Referenz oder eine R-Referenz ab.

Das funktioniert genauso, wie Typ Abzug beim Aufruf einer template Funktion funktioniert.

template<typename T> 
void foo(T t); 

T wird nie durch seinen einen Referenztyp abgeleitet werden - es wird immer ein Werttyp sein, wenn abgeleitet.

auto folgt fast identische Regeln:

template<typename T> 
void foo(T&& t); 

die einigermaßen gut bekannt „Universal-Referenz“ ist analog zu einer Variablen vom Typ auto&&.

+0

autoritative Antworten verdienen Zitate ;-) Andy Prowl hat es trotzdem gut kommentiert, es ist leider keine Antwort. Der Standard sagt das, trotzdem würde ich gerne historische Gründe und/oder starke Argumente darüber wissen, wie es nicht ohne zu viel Mühe sein könnte. –