Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

31.08.2016, 09:49

C++ - Gute Verwendung des Schlüsselwortes 'auto'

Hallo zusammen,

ich lese zurzeit das Buch "Effektives modernes C++" von Scott Meyers -> Link
Das zweite Kapitel dreht sich um das Schlüsselwort "auto". Der Autor plädiert dafür, "auto" einer expliziten Typdeklaration vorzuziehen, weil das zahlreiche Vorteile bietet
(z.B. es gibt kein Problem mehr mit uninitialisierten Variablen, "auto" sei im Allgemeinen immun gegen Typdiskrepanzen, es vereinfacht das Refactoring und es ist weniger Schreibarbeit).
Das leuchtet mir im Großen und Ganzen alles ein. Trotzdem habe ich mich gefragt, ob es nicht nervig ist, nicht mehr auf einen Blick sehen zu können, welchen Typ eine Variable hat.
Im weiteren Verlauf schlägt er vor, dem Problem, dass "auto" bei Proxy-Typen unerwünschte Typen ableitet, mit einem Cast des Initialisierungsausdrucks zu begegnen.

Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
//Gibt ein Vektor vom Typen bool zurück, wobei das Bit mit dem Index 5 anzeigt, ob w eine hohe Priorität hat, oder nicht
std::vector<bool> features(const Widget& w);

Widget w;

//speichert die Priorität von w in highPriority
auto highPriority = static_cast<bool>(features(w)[5]);


Der Grund, warum hier gecastet werden muss, ist dass der operator[] für std::vector<bool> ein Objekt des Types std::vector<bool>::reference zurückgibt.
Das ist so, weil C++ Referenzen auf Bits verbietet, der operator[] für std::vector<T> aber ein T& liefert. Das Objekt des Types std::vector<bool>::reference wird dann implizit in einen bool konvertiert. Da "auto" aber kein bool ist, sondern sich den Typ aus dem Rückgabewert ableitet, hat die Variable highPriority dann den Typen std::vector<bool>::reference.

Frage: Warum sollte man hier dann überhaupt "auto" verwenden? Wäre es nicht sehr viel einfacher nur

C-/C++-Quelltext

1
 bool highPriority = features(w)[5];
zu schreiben?

lg superolelli

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

31.08.2016, 10:52

Trotzdem habe ich mich gefragt, ob es nicht nervig ist, nicht mehr auf einen Blick sehen zu können, welchen Typ eine Variable hat.

Nunja, in der Regel sollte es aus dem Kontext klar sein, welchen Typ eine Variable hat. Abgesehen davon sollte jede brauchbare IDE dir den Typ eines Objektes anzeigen können. Dennoch kann es manchmal schon nervig sein, weshalb ich persönlich auto zwar oft aber bei weitem nicht ausschließlich verwende.


Frage: Warum sollte man hier dann überhaupt "auto" verwenden? Wäre es nicht sehr viel einfacher nur

C-/C++-Quelltext

1
 bool highPriority = features(w)[5];
zu schreiben?

Nun, wenn man sonst überall auto verwendet, würde man wohl um der Konsistenz willen das hier so machen. Ich persönlich würde aber auch einfach bool highPriority = features(w)[5]; schreiben, wenn wir mal die Tatsache ignorieren, dass std::vector<bool> kaputt ist und absolut niemals verwendet werden sollte... ;)

3

31.08.2016, 12:22

Ich denke auch, dass es da mehrere Herangehensweisen gibt:

Wenn du auf maximale flexibilität des Codes setzten willst, dann solltest du -nach Möglichkeit- überall auto verwenden, da sich - wie dot schon schrieb- aus dem Kontext/Namen der Variablen ihr eindeutiger Zweck ergeben sollte (der darunterliegende Typ kann sich ja ändern, solange die "Funktionalität" gewahrt bleibt.

Wenn man mehr Wert auf "lazy Coding" setzen möchte oder sich nicht die Regeln der Typen-Ableitung von auto merken möchte, dann würde ich wohl auch den Typ der Variable voranstellen, sofern die Tippersparnis gross genug ist ("da vorne wie hinten": wohl meistens ;) )

Falls du in einem Team arbeitest und ihr ne Coding Convetion habt, kann man ja festlegen ob man immer auto verwendet und welche Spezialfälle auszunehmen sein dürfen.


Hier auch noch ein alter, aber nicht kalter (Pre-C++17-)Artikel zu auto

4

31.08.2016, 12:47

Danke für die Antworten :)

Mir war gar nicht klar, dass die IDE mir den Typen trotzdem anzeigt, auch wenn ich auto verwende (Habe es nämlich bis jetzt so gut wie nie verwendet).
Aber so wie sich das anhört, sollte ich es in Betracht ziehen, ab jetzt auto tendenziell den Vorzug zu geben (ohne es zu übertreiben :) ).
Danke auch für den Artikel.

Was ist mit Membervariablen, die in einer Headerdatei deklariert sind. Reicht es auto, wenn ich die im Konstruktor initialisiere, oder müsste ich das direkt im Header machen?
Und wenn ja, sollte ich dann trotz des Initialisierungszwangs im Header auto hierfür benutzen?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

31.08.2016, 13:25

Was ist mit Membervariablen, die in einer Headerdatei deklariert sind. Reicht es auto, wenn ich die im Konstruktor initialisiere, oder müsste ich das direkt im Header machen?
Und wenn ja, sollte ich dann trotz des Initialisierungszwangs im Header auto hierfür benutzen?

auto kann nur in Deklarationen von statischen Membervariablen verwendet werden... ;)

buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

6

31.08.2016, 13:37

Ich verwende so gut wie nie auto. Der Grund ist, dass man eben nicht am Namen einer Variable den Typen erkennt.
Es sei denn man verwendet noch ungarische Notation.
Meines Wissens nach ist "auto" auch nur wegen Templates eingeführt worden und sollte auch nur in diesem Zusammenhang
verwendet werden.
Außerdem ist der Code wesentlich leichter lesbar. Man will ja nicht an jeder Stelle mit der Maus stehen bleiben
und auf das Popup der IDE warten. Oder vielleicht bin ich da nur zu hektisch.

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

7

31.08.2016, 14:05

Nein, nein, nochmal nein. auto ist der Lebensretter des täglichen C++-Codens, es erspart einem primär das mühsame Ausschreiben länglicher Typen. Nur im Zusammenhang mit template-Operationen, deren Ergebnistyp abhängig von den template-Parametern ist, braucht man wirklich auto. Das ist wahrscheinlich das, was Du aufgeschnappt hast. Ungarische Notation ist tot und sollte es auch bleiben. Denn man braucht eigentlich nicht wirklich den genauen Typen zu wissen. Bei einem

Quellcode

1
auto it = std::find_if(...);
ist auch so klar, welchen Typ die Variable hat. Wer nur aufgrund von möglichen seltenen Nicht-Genau-Das-Was-Ich-Erwarte-Problemen alle Typen von Hand ausschreibt, verweigert sich meiner Meinung nach einfach nur der Zukunft.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

31.08.2016, 14:09

Ich verwende so gut wie nie auto. Der Grund ist, dass man eben nicht am Namen einer Variable den Typen erkennt.

Wenn aus dem Namen und Kontext einer Variable normalerweise nicht klar ist, um was es sich wohl handeln muss, dann solltest du definitiv mal die Art und Weise wie du deinen Code strukturierst und Dinge benennst hinterfragen... ;)

Es sei denn man verwendet noch ungarische Notation.

Von Ungarischer Notation würde ich erstens abraten und zweitens würde die auch nix ändern, weil man – zumindest bei der "richtigen" ungarischen Notation – auch nicht den Datentyp in den Namen tut... ;)


Meines Wissens nach ist "auto" auch nur wegen Templates eingeführt worden und sollte auch nur in diesem Zusammenhang verwendet werden.

auto wurde definitiv nicht nur wegen Templates eingeführt sondern ist generell sehr nützlich. Ich würde sogar soweit gehen, zu sagen, dass auto für Nicht-Template Code wesentlich mehr Vorteile bringt als für Templates. Kleines Beispiel:

ohne auto:

C-/C++-Quelltext

1
  std::vector<std::tuple<std::string, int, double>>::const_iterator found = std::find_if(std::begin(my_stuff), std::end(my_stuff), ...);

mit auto:

C-/C++-Quelltext

1
  auto found = std::find_if(std::begin(my_stuff), std::end(my_stuff), ...);

Man beachte, dass die zweite Variante nicht nur kürzer und wesentlich besser lesbar ist, sondern auch generischer. Wenn ich z.B. statt einem std::vector auf einmal eine andere Art von Container verwenden wollte, müsste ich in allem Code, der bisher mit dem std::vector gearbeitet hat überall die Datentypen anpassen. Dank auto funktioniert der selbe Code nun einfach so für alle sequentiellen Container; ich könnte statt dem std::vector sogar auf einmal ein stinknormales Array verwenden ohne auch nur einen Buchstaben anpassen zu müssen...

Außerdem ist der Code wesentlich leichter lesbar.

Das kommt darauf an. Meistens sollte aus dem Kontext sowieso klar sein, um was es sich bei einer Variable handelt und wie sie verwendet werden kann.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

9

31.08.2016, 15:14

Ich würde sogar soweit gehen, zu sagen, dass auto für Nicht-Template Code wesentlich mehr Vorteile bringt als für Templates. Kleines Beispiel:

Ich glaube das was du mit deinem Beispiel zeigst ist genau das worum es hier beim Thema Templates ging.

Der Grund ist, dass man eben nicht am Namen einer Variable den Typen erkennt.

Ich glaube da vertust du dich und musst noch mal drüber nach denken. Ob ich jetzt auto oder den konkreten Typ hinschreibe ändert ja am Namen der Variable nichts. Wie dot schon mehrfach gesagt hat hast du deine Variablen hoffentlich so benannt dass der Typ dadurch klar wird.

Auto ist ne super Sache. Genau wie var bei C# und andere Sprachen bieten so etwas teilweise auch an. Du sollst und musst bei deinem Code oft einfach gar nicht genau über Typen nachdenken. Du programmierst quasi auf einem höheren Abstraktionsgrad. Es geht ja am Ende darum dass du deine Problemlösung ausdrückst und nicht darum dass du dich mit Datentypen rum ärgerst. Die Vorteile hat er TE ja selbst schon genannt und die sollten soweit klar sein. Das mag am Anfang vielleicht erst mal eine kleine Umstellung sein, an sich lohnt es sich aber. Wenn es wirklich zu verwirrend ist dann mach vielleicht mal einen kleinen Abstecher in die funktionale Welt. Guck dir vielleicht einfach mal ein wenig Haskell oder so an. Dort wird auch ziemlich generisch entwickelt und du abstrahierst so weit vom konkreten Typen weg wie nur Möglich. Mit vielen Vorteilen eben. Und auto bedeutet ja nicht dass die Typinformation fehlt. Der Typ muss zur Übersetzungszeit bekannt sein. Deshalb kann dir auch deine IDE sagen welchen Typ so eine Variable hat. Natürlich musst du es nicht immer benutzen, mir würde aber grad spontan keine Situation einfallen in welcher ich es nicht benutze.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Helmut

5x Contest-Sieger

Beiträge: 692

Wohnort: Bielefeld

  • Private Nachricht senden

10

31.08.2016, 15:54

Ich bin da auf buggypixels Seite. Ob ich beispielsweise auto istLeer = <komplizierterAusdruck>; oder das selbe mit bool statt auto schreibe macht vom Schreibaufwand keinen Unterschied. Aber die Variante mit bool ist etwas typsicherer und lesbarar. Klar kann man das auch vom Namen her erahnen, aber manchmal möchte man es halt auch genau wissen (bool, BOOL oder int). Oder man will eine Datenstruktur bezüglich Alignment oder Größe begutachten. Da spielen die Namen keine Rolle und man schaut automatisch auf die linke Seite. Wenn da dann auto steht nützt das einem nichts. Ein anderes Beispiel ist, wenn man sich in eine fremde Codebase einarbeitet. Wenn man dann ständig auto liest erschwert das mMn nur das Leseverständnis.
Bei Iteratoren und co. hat auto natürlich seine Daseinsberechtigung.
Sei stets geduldig gegenüber Leuten, die nicht mit dir übereinstimmen. Sie haben ein Recht auf ihren Standpunkt - trotz ihrer lächerlichen Meinung. (F. Hollaender)

Werbeanzeige