C++ auto
-
Hallo,
ich habe das Schlüsselwort "auto" eigentlich nie gebrauchen müssen, allerdings würde ich gerne wissen, wann man es verwenden, und wann nicht, sollte.Folgendes habe ich verstanden:
"auto" steht für einen unbekannten Datentyp, den der Compiler selbst bestimmt.Folgende Fragen:
- Bei einem gut architektierten Programm, sollte eine Verwendung von "auto" doch überflüssig sein, oder?
- Ist es eine Art "Designfehler", "auto" zu verwenden?
- Wann würdet ihr "auto" verwenden?
- Designfrage, Beispiel:
for( std::vector<int>::iterator it( Vec.begin( ) ); ... )
oder:
for( auto it( Vec.begin( ) ); ... )
Danke im voraus!
-
eigentlich genau dann wenn der zu verwendende datentyp zu lang zu schreiben ist und selbst bestimmt werden kann
z.B.
// statt std::map<std::string, std::vector<std::pair<FooBar, LolString>>>::const_iterator it = foo(); // lieber auto it = foo();
-
Sobald ich mich auf C++11 stützen kann (also alle Compiler es vollständig sprechen), werde ich auto überall benutzen, wo ich den Kram nicht in einen bestimmten Datentyp zwingen will.
auto it = mymap.begin(); // Hurra! auto closure = [&]{ return *it; } // Yay! auto &&key = closure().first; // Juhu!
Eines der herausstehenden Features von C++ ist ja gerade, dass am Typsystem eine turing-komplette Sprache hängt. Was soll ich mir den Typ selbst raussuchen, wenn der Compiler ihn schon kennt?
-
Folgende Fragen:
- Bei einem gut architektierten Programm, sollte eine Verwendung von "auto" doch überflüssig sein, oder?
- Ist es eine Art "Designfehler", "auto" zu verwenden?
- Wann würdet ihr "auto" verwenden?
- Designfrage, Beispiel:
1.) Dem kann ich nicht zustimmen.
2.) Nein, dem kann ich auch nicht zustimmen.
3.) Immer wenn möglich und ich den Typ nicht explizit erzwingen will.
4.) letzteres
-
seldon schrieb:
Eines der herausstehenden Features von C++ ist ja gerade, dass am Typsystem eine turing-komplette Sprache hängt.
Die gängigen Programmiersprachen sind Turing-vollständig. Dies schließt konventionelle prozedurale Sprachen wie C und objektorientierte Sprachen wie C++ und Java ein. Auch Sprachen, die nach weniger geläufigen Paradigmen entworfen wurden, unter anderem funktionale Programmiersprachen wie LISP und Haskell und Sprachen für Logikprogrammierung wie Prolog sind Turing-vollständig.
-
Zeus: Lies genauer. Er hat nicht geschrieben, dass C++ Turing-vollständig ist.
-
Michael E. schrieb:
Zeus: Lies genauer. Er hat nicht geschrieben, dass C++ Turing-vollständig ist.
Noch mal gelesen, doch hat er, nagut, was wollte er dann damit ausdrücken, dass was ich nicht verstanden habe?
-
Ich bezog mich damit auf Template-Metaprogrammierung. Generell geht es darum, dass ein C++-Compiler in Bezug auf das Typsystem sehr schlau und es deshalb üblich ist, ihn richtig ackern zu lassen. Warum sollte man hier anfangen, ihm alles genau vorzubeten? Er weiß doch schon, worum es geht.
-
Kóyaánasqatsi schrieb:
"auto" steht für einen unbekannten Datentyp, den der Compiler selbst bestimmt.
Nein. Das hat nichts mit unbekannten Typen zu tun. auto ist einfach nur eine kürzere Schreibweise.
-
Kóyaánasqatsi schrieb:
Folgendes habe ich verstanden:
"auto" steht für einen unbekannten Datentyp, den der Compiler selbst bestimmt.Falsch. Der Datentyp ist in den meisten Fällen bekannt. Ausnahmen sind Lambdas, die keinen spezifizierten Datentyp haben.
Folgende Fragen:
- Bei einem gut architektierten Programm, sollte eine Verwendung von "auto" doch überflüssig sein, oder?
- Ist es eine Art "Designfehler", "auto" zu verwenden?
- Wann würdet ihr "auto" verwenden?
- Designfrage, Beispiel:
for( std::vector<int>::iterator it( Vec.begin( ) ); ... )
oder:
for( auto it( Vec.begin( ) ); ... )
- nein.
- nein.
- Immer, wenn der Typ der Variable vom Typ des Initialisierers abhängt. Sprich, wenn ich den Typ der Variable ändern müsste, sollte es mir einfallen, den Typ einer Variablen des Ausdrucks zu ändern.
- auf jeden Fall auto - und nicht vec als Namen sondern was anderes. Vielleicht stellt sich ja raus, dass ich später den vector durch eine Liste ersetzen möchte... Ich würds allerdings noch "C++11iger" machen. In MSVC 2010:
for (auto it = begin(Vec); ...)
In MSVC 2011:
for (auto& e : Vec)
In GCC weiß ich nicht, wie weit er range based for schon unterstützt.
-
Kóyaánasqatsi schrieb:
"auto" steht für einen unbekannten Datentyp, den der Compiler selbst bestimmt.
Nein. auto steht für "Ich bin zu faul, den Typen hinzuschreiben, und du weißt eh, was gemeint ist".
Kóyaánasqatsi schrieb:
- Bei einem gut architektierten Programm, sollte eine Verwendung von "auto" doch überflüssig sein, oder?
Nein.
Kóyaánasqatsi schrieb:
- Ist es eine Art "Designfehler", "auto" zu verwenden?
Nein.
Kóyaánasqatsi schrieb:
- Wann würdet ihr "auto" verwenden?
Wann immer möglich.
Kóyaánasqatsi schrieb:
- Designfrage, Beispiel:
Keins von beiden. Explizite initialisierung finde ich bei Rückgabewerten hässlich. Außerdem std::begin/std::end, um generisch zu bleiben.
auto it = begin(v);
Oder natürlich gleich ranged based for...
-
Kellerautomat schrieb:
Kóyaánasqatsi schrieb:
"auto" steht für einen unbekannten Datentyp, den der Compiler selbst bestimmt.
Nein. auto steht für "Ich bin zu faul, den Typen hinzuschreiben, und du weißt eh, was gemeint ist".
Das ist aber nicht korrekt. Auto kann Code generischer machen. Einfaches Beispiel: Eine Bibliothek, die man benutzt, arbeitet im Moment mit 32 Bit Genauigkeit bei Fließkommatypen, kann aber in 5 Jahren, wenn der Speicher oder Geschwindigkeitsunterschied komplett irrelevant ist, durchaus auf 62 Bit Genauigkeit umsteigen. Dementsprechend liefern auch alle Methoden im Moment noch float.
Mit auto erspart man sich nerviges ersetzen der floats durch double später.
Klar, mit typedef bekommt man das auch hin, aber imo ist es mit auto schöner, weil man da später wirklich gar nichts ändern muss. Einfach neu kompilieren.
edit: Ich merk grad, dass du das damit nicht wirklich gemeint hast. Ich lass es aber trotzdem so stehen, vielleicht findet's irgendwer hilfreich
-
TravisG schrieb:
durchaus auf 62 Bit Genauigkeit umsteigen.
Wer weiß, vielleicht haben wir bald 126-Bit Plattformen.
-
Die Genauigkeit hat mit der Plattform genau nichts zu tun
Edit:
TravisG schrieb:
Mit auto erspart man sich nerviges ersetzen der floats durch double später.
Klar wäre das ein Sinn von auto, aber man sieht nicht selten ein
typedef float real;
bzw. jetzt
using real = float;
um gerade diesem Ersetzen vorzubeugen.
-
Cyres schrieb:
Die Genauigkeit hat mit der Plattform genau nichts zu tun
Oha? Wo ist denn die Genauigkeit festgelegt?
-
Michael E. schrieb:
Cyres schrieb:
Die Genauigkeit hat mit der Plattform genau nichts zu tun
Oha? Wo ist denn die Genauigkeit festgelegt?
In der Anzahl der Bits in einer Variablen, es war auch im 8Bit-System Möglich 64-Bit-Typen zu definieren. Die 64-Bit Architektur bietet zwar einfacherere Möglichkeiten mit eben diesen umzugehen (größere ALU), hat aber nichts mit der eigentlichen Genauigkeit zu tun.
-
Das nimmt man auch wenn man ein Auto Spiel programmiert brumm brumm bruuuummm.
-
Ich sehe das so. In deinem Code taucht der Datentyp einer Variable nur einmal auf und zwar bei der Definition. Im restlichen Verlauf des Codes benutzt du nur noch den Variablennamen. Der Variablenname begeleitet dich in deinem Programm, nicht der Datentyp. Insofern ist der Datentyp nicht so relevant, wie die Aussagekräftigkeit eines Namens.
Dein Code sollte sich einfach und bequem lesen und verstehen lassen. Selbst für sich sprechen. Ein Variablenname ist das A und O hierbei. Da interessiert der Datentyp nicht. Wenn interessiert das T<..>::XYZ vor einem Iterator, arbeitet und schreibe sauberen Code und minimiere alle redundaten Information, die nur den Lese- und Verständnisfluss des Codes erschweren.
Mein Tipp, benutze auto wo es geht und "schön" aussieht. Mit der Zeit wirst du es raus haben und die Community sich daran gewöhnen. Es ist so wie mit dem var in C#. Da hat es auch ein Weilchen gedauert, bis man damit warm wurde.
-
Cyres schrieb:
Die Genauigkeit hat mit der Plattform genau nichts zu tun
Edit:
TravisG schrieb:
Mit auto erspart man sich nerviges ersetzen der floats durch double später.
Klar wäre das ein Sinn von auto, aber man sieht nicht selten ein
typedef float real;
bzw. jetzt
using real = float;
um gerade diesem Ersetzen vorzubeugen.
Ja, wie gesagt:
TravisG schrieb:
Klar, mit typedef bekommt man das auch hin, aber imo ist es mit auto schöner, weil man da später wirklich gar nichts ändern muss. Einfach neu kompilieren.
Und was machst du mit typedef, wenn manche Funktionen aus irgendwelchen Legacy-Gründen am Ende doch noch float zurückgeben, oder wenn früher ein paar Funktionen aus irgendwelchen Gründen schon double zurückgegeben haben, und in Zukunft dafür einen 128-Bit Datentyp liefern?
typedef float real; typedef double betterReal;
Wäh.
-
Cyres schrieb:
Michael E. schrieb:
Oha? Wo ist denn die Genauigkeit festgelegt?
In der Anzahl der Bits in einer Variablen
Wer sagt mir denn, wie die Bits genutzt werden?