C++ auto
-
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?
-
Michael E. schrieb:
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?
Es geht ja nicht darum, wie sie benutzt werden, sondern wieviele benutzt werden. Dass die Bits für eine 64-Bit Zahl mit einer 64-Bit-Architektur besser verarbeitet werden können, ist mir klar
-
Cyres schrieb:
Michael E. schrieb:
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?
Es geht ja nicht darum, wie sie benutzt werden, sondern wieviele benutzt werden.
...
-
Cyres schrieb:
Es geht ja nicht darum, wie sie benutzt werden, sondern wieviele benutzt werden.
Es kommt sehr wohl darauf an, wie sie benutzt werden. Vielleicht bilden je vier Bits eine Ziffer im BCD-Format. Vielleicht werden ein paar Bits überhaupt nicht benutzt. Vielleicht wird eine Darstellung gemäß IEEE 754 benutzt, vielleicht gibt es aber auch keinen Exponenten. Wie kannst du nun aus der Anzahl der Bits auf die Genauigkeit schließen?
-
Explizit ist besser als implizit, von daher ziehe ich den Typnamen auto vor.
So zeilenlange Typnamen wie hier als Beispiel gebracht entstehen bei mir auch nicht, da ich einzelne Typen frühzeitig als typedef verpacke.typedef std::shared_ptr<Widget> WidgetPtr; typedef std::map<std::string, WidgetPtr> WidgetMapping; typedef std::vector<WidgetMapping> WidgetMappings; WidgetMappings m_mapping;
anstatt
std::vector<std::map<std::string, std::shared_ptr<Widget>>> m_mapping;
-
@Ethon,
Wo genau siehst du nun den Vorteil gegenüberauto
, wenn irgendwo im Code fernab von deinen Typdefinitionen nun das folgende steht:WidgetMappings mapping = getWidgetMappings();
Gegenüber eben
auto
?auto mapping = getWidgetMappings();
Bei
auto
geht es viel eher darum Redundanz zu verhindern. Heisst der Typ, bzw. vielleicht besser die benötigte Schnittstelle, ist aus dem Kontext heraus bereits klar.Grüssli
-
Es geht nicht um Faulheit, sondern um Lesbarkeit. Wo die Erwähnung des expliziten Typs keinen wesentlichen Zusatzgewinn bezüglich Lesbarkeit bringt, da ist auto angebracht. Beispielsweise wenn ich ein std::map habe und ich möchte wissen, ob ein Element darin vorkommt, dann schreibe ich doch einfach:
auto it = myMap.find(myKey); if (it != myMap.end()) { ... }
Wenn ich diesen Codeausschnitt lese, dann verstehe ich auf Anhieb, was hier gemacht wird. Die Erwähnung des Iteratortyps bringt mir keinen Vorteil.
Man sollte sich bei der Formulierung von Code nicht an Bequemlichkeit orientieren, sondern klaren nachvollziehbaren Code schreiben. Das erhöht die Wartbarkeit und damit die Lebensdauer von Code.
-
Man sollte sich also nicht die Frage stellen
"Wieso sollte ich automatische Typdeduzierung der expliziten Typangabe vorziehen?" sondern
"Wieso sollte ich die explizite Typangabe der automatischen Typdeduzierung vorziehen?"