Ich habe eine Konferenz von Herb Sutter gesehen, in der er jeden C ++ - Programmierer ermutigt, sie zu verwenden auto
.
Ich musste vor einiger Zeit C # -Code lesen, wo er häufig var
verwendet wurde, und der Code war sehr schwer zu verstehen. Bei jeder var
Verwendung musste ich den Rückgabetyp auf der rechten Seite überprüfen. Manchmal mehr als einmal, weil ich den Typ der Variablen nach einer Weile vergessen habe!
Ich weiß, dass der Compiler den Typ kennt und ich ihn nicht schreiben muss, aber es ist allgemein anerkannt, dass wir Code für Programmierer schreiben sollten, nicht für Compiler.
Ich weiß auch, dass das einfacher zu schreiben ist:
auto x = GetX();
Als:
someWeirdTemplate<someOtherVeryLongNameType, ...>::someOtherLongType x = GetX();
Dies wird jedoch nur einmal geschrieben und der GetX()
Rückgabetyp wird mehrmals überprüft, um zu verstehen, welchen Typ er x
hat.
Das hat mich gefragt: auto
Ist C ++ - Code schwieriger zu verstehen?
auto
kann die Lesbarkeit von Objekten oft erschweren, wenn sie bereits schwer lesbar sind, z. B. zu lange Funktionen, schlecht benannte Variablen usw. Bei kurzen Funktionen mit anständig benannten Variablen sollte die Kenntnis der Typen eine der Kategorien # 1 easy oder # 2 irrelevant sein.auto
ähnelt der Bestimmung des Verwendungszeitpunktstypedef
. Es liegt an Ihnen zu bestimmen, wann es behindert und wann es hilft.auto x = GetX();
, wähle einen besseren Namen als derx
, der dir tatsächlich sagt, was er in diesem speziellen Kontext tut ... das ist sowieso oft nützlicher als sein Typ.Antworten:
Kurze Antwort: Meiner Meinung nach
auto
sollten Sieauto
standardmäßig verwenden, es sei denn, Sie möchten ausdrücklich eine Konvertierung. (Etwas genauer: "... es sei denn, Sie möchten explizit einen Typ festlegen, was fast immer daran liegt, dass Sie eine Konvertierung wünschen.")Längere Antwort und Begründung:
Schreiben Sie einen expliziten Typ (anstatt
auto
) nur dann, wenn Sie sich wirklich explizit auf einen Typ festlegen möchten, was fast immer bedeutet, dass Sie explizit eine Konvertierung in diesen Typ durchführen möchten. Ich erinnere mich an zwei Hauptfälle:initializer_list
Überraschung, dieauto x = { 1 };
ableitetinitializer_list
. Wenn Sie nicht möchteninitializer_list
, geben Sie den Typ an, dh fordern Sie explizit eine Konvertierung an.auto x = matrix1 * matrix 2 + matrix3;
ein Hilfs- oder Proxy-Typ erfasst wird, der für den Programmierer nicht sichtbar sein soll. In vielen Fällen ist es in Ordnung und harmlos, diesen Typ zu erfassen, aber manchmal, wenn Sie wirklich wollen, dass er zusammenbricht und die Berechnung durchführt, sagen Sie den Typ - dh fragen Sie erneut explizit nach einer Konvertierung.Andernfalls
auto
standardmäßig routinemäßig verwenden , da die Verwendung vonauto
Fallstricken vermeidet und den Code korrekter, wartbarer, robuster und effizienter macht. Etwa in der Reihenfolge von am wenigsten wichtig, im Sinne von "Schreiben Sie zuerst für Klarheit und Korrektheit":auto
Garantien erhalten Sie den richtigen Typ. Wie das Sprichwort sagt, wenn Sie sich wiederholen (sagen Sie den Typ überflüssig), können und werden Sie lügen (verstehen Sie es falsch). Hier ein übliches Beispiel:void f( const vector<int>& v ) { for( /*…*
- Wenn Sie an dieser Stelle den Typ des Iterators explizit schreiben, möchten Sie sich daran erinnern, dass Sie geschrieben habenconst_iterator
(oder?), Während Sie esauto
einfach richtig machen.auto
wird der Code angesichts von Änderungen robuster, da er bei Änderungen des Ausdruckstypsauto
weiterhin in den richtigen Typ aufgelöst wird. Wenn Sie stattdessen einen expliziten Typ festlegen, werden beim Ändern des Ausdruckstyps stille Konvertierungen eingefügt, wenn der neue Typ in den alten Typ konvertiert wird, oder unnötige Build-Unterbrechungen, wenn der neue Typ weiterhin wie der alte Typ funktioniert, aber nicht in den alten konvertiert wird Typ (zum Beispiel, wenn Sie eine Änderungmap
an eineunordered_map
, die immer in Ordnung ist , wenn Sie nicht auf Bestellung angewiesen sind, verwendenauto
für Ihre Iteratoren werden Sie nahtlos wechseln vonmap<>::iterator
zuunordered_map<>::iterator
, jedoch unter Verwendung vonmap<>::iterator
Überall explizit bedeutet, dass Sie Ihre wertvolle Zeit mit einem mechanischen Code-Fixing verschwenden, es sei denn, ein Praktikant kommt vorbei und Sie können die langweilige Arbeit auf sich nehmen.auto
garantiert wird, dass keine implizite Konvertierung erfolgt, wird standardmäßig eine bessere Leistung garantiert. Wenn Sie stattdessen den Typ angeben und eine Konvertierung erforderlich ist, erhalten Sie häufig im Hintergrund eine Konvertierung, unabhängig davon, ob Sie dies erwartet haben oder nicht.auto
ist Ihre einzige gute Option für schwer zu buchstabierende und nicht auszusprechende Typen wie Lambdas und Template-Helfer, ohne auf sich wiederholendedecltype
Ausdrücke oder weniger effiziente Indirektionen wie zuzugreifenstd::function
.auto
wird weniger getippt. Ich erwähne dies der Vollständigkeit halber, weil es ein häufiger Grund ist, es zu mögen, aber es ist nicht der größte Grund, es zu benutzen.Daher: Ziehe es vor,
auto
standardmäßig zu sagen . Es bietet so viel Einfachheit, Leistung und Klarheit, dass Sie sich selbst (und die zukünftigen Betreuer Ihres Codes) nur verletzen, wenn Sie dies nicht tun. Festschreiben Sie einen expliziten Typ nur dann, wenn Sie ihn wirklich meinen, was fast immer bedeutet, dass Sie eine explizite Konvertierung wünschen.Ja, dazu gibt es (jetzt) ein GotW .
quelle
auto x = static_cast<X>(y)
. Dasstatic_cast
macht deutlich, dass die Konvertierung absichtlich ist und vermeidet Compiler-Warnungen über die Konvertierung. Normalerweise ist es nicht so gut, Compiler-Warnungen zu vermeiden, aber ich kann keine Warnung über eine Konvertierung erhalten, die ich beim Schreiben sorgfältig in Betracht gezogen habestatic_cast
. Ich würde das zwar nicht tun, wenn es jetzt keine Warnungen gibt, aber ich möchte in Zukunft Warnungen erhalten, wenn sich die Typen auf eine potenziell gefährliche Weise ändern.auto
ist, dass wir uns bemühen sollten, gegen Schnittstellen zu programmieren (nicht im Sinne von OOP), nicht gegen bestimmte Implementierungen. Genau so ist es mit Vorlagen. Beschweren Sie sich über "schwer lesbaren Code", weil Sie einen Vorlagentyp-Parameter habenT
, der überall verwendet wird? Nein, das glaube ich nicht. Auch in Templates wird gegen eine Schnittstelle codiert, was viele Leute Entenschreiben zur Kompilierungszeit nennen.auto
.auto
Variablen nicht korrekt , aber fast alle tun es korrekt mit expliziter Typspezifikation. Niemand benutzt IDE? Jeder benutzt nur int / float / bool Variablen? Jeder bevorzugt externe Dokumentation für Bibliotheken anstelle von selbst dokumentierten Kopfzeilen?=
RHS machen bei keiner anderen Interpretation viel Sinn (Init-Liste in Klammern , aber Sie müssen wissen, was Sie initialisieren, was ein Oxymoron istauto
). Die eine , die ist überraschend istauto i{1}
auch herzuleiteninitializer_list
, trotz damit nicht sagen , nehmen diese verspannt init-Liste , sondern diesen Ausdruck nehmen und seine Art verwenden ... aber wir bekommeninitializer_list
es auch. Zum Glück behebt C ++ 17 das alles gut.Es ist eine Situation von Fall zu Fall.
Manchmal ist Code schwieriger zu verstehen, manchmal nicht. Nimm zum Beispiel:
ist definitiv leicht zu verstehen und definitiv leichter zu schreiben als die eigentliche Iterator-Deklaration.
Ich benutze C ++ schon eine Weile, aber ich kann garantieren, dass ich bei meinem ersten Versuch einen Compilerfehler bekomme, weil ich das vergesse
const_iterator
und mich anfangs für das entscheiden würdeiterator
... :)Ich würde es für solche Fälle verwenden, aber nicht dort, wo es den Typ tatsächlich verschleiert (wie Ihre Situation), aber dies ist rein subjektiv.
quelle
std::map<int, std::string>::const_iterator
, sodass der Name Ihnen sowieso nicht viel über den Typ verrät.int
und der Wert iststd::string
. :)it->second
da es ein const iterator ist. Alle diese Informationen sind Wiederholungen der vorherigen Zeileconst std::map<int, std::string>& x
. Wenn Sie mehrmals Dinge sagen, ist dies gelegentlich eine bessere Information, aber dies ist keineswegs eine allgemeine Regel :-)for (anX : x)
, noch deutlicher zu machen, dass wir nur darüber nachdenkenx
. Der Normalfall, in dem Sie einen Iterator benötigen, ist, wenn Sie den Containerx
const&
Sieh es anders an. Schreibst du:
oder:
Manchmal hilft es nicht, den Typ explizit zu buchstabieren.
Die Entscheidung, ob Sie den Typ angeben müssen, stimmt nicht mit der Entscheidung überein, ob Sie den Code durch Definieren von Zwischenvariablen auf mehrere Anweisungen aufteilen möchten. In C ++ 03 wurden die beiden verknüpft. Sie können sich vorstellen,
auto
wie Sie sie trennen können.Manchmal kann es nützlich sein, die Typen explizit anzugeben:
gegen
In Fällen, in denen Sie eine Variable deklarieren,
auto
lässt using den Typ unausgesprochen, so wie er in vielen Ausdrücken vorkommt. Sie sollten wahrscheinlich selbst entscheiden, wann dies die Lesbarkeit verbessert und wann es behindert.Sie können argumentieren, dass das Mischen von vorzeichenbehafteten und nicht vorzeichenbehafteten Typen zunächst ein Fehler ist (einige argumentieren außerdem, dass man überhaupt keine nicht vorzeichenbehafteten Typen verwenden sollte). Der Grund , warum es wohl ein Fehler ist, ist, dass die Typen der Operanden aufgrund des unterschiedlichen Verhaltens von entscheidender Bedeutung sind. Wenn es schlecht ist, die Typen Ihrer Werte zu kennen, ist es wahrscheinlich auch nicht schlecht, sie nicht zu kennen. Vorausgesetzt, der Code ist nicht bereits aus anderen Gründen verwirrend, macht das
auto
OK, oder? ;-)Insbesondere beim Schreiben von generischem Code gibt es Fälle, in denen der tatsächliche Typ einer Variablen nicht wichtig sein sollte. Entscheidend ist jedoch, dass die erforderliche Schnittstelle erfüllt wird. So
auto
bietet eine Abstraktionsebene , wo Sie die Art ignorieren (aber natürlich nicht der Compiler nicht, weiß es). Wenn Sie auf einer geeigneten Abstraktionsebene arbeiten, kann dies die Lesbarkeit erheblich verbessern. Wenn Sie auf einer "falschen" Ebene arbeiten, wird das Lesen des Codes zu einem Problem.quelle
auto
können Sie benannte Variablen mit unbenennbaren oder uninteressanten Typen erstellen. Sinnvolle Namen können nützlich sein.sizeof
Sie unsigned sind.IMO, Sie sehen das so ziemlich umgekehrt.
Es geht nicht darum
auto
, zu Code zu führen, der nicht lesbar oder noch weniger lesbar ist. Es ist eine Frage der Hoffnung, dass ein expliziter Typ für den Rückgabewert die Tatsache ausgleichen wird, dass (anscheinend) nicht klar ist, welcher Typ von einer bestimmten Funktion zurückgegeben wird.Zumindest ist das nach meiner Meinung Ihr Problem, wenn Sie eine Funktion haben, deren Rückgabetyp nicht sofort offensichtlich ist. Was die Funktion tut, sollte aus ihrem Namen ersichtlich sein, und der Typ des Rückgabewerts sollte aus dem, was sie tut, ersichtlich sein. Wenn nicht, ist das die eigentliche Ursache des Problems.
Wenn es hier ein Problem gibt, ist es nicht mit
auto
. Es ist mit dem Rest des Codes verbunden, und die Chancen stehen gut, dass der explizite Typ nur als Hilfsmittel ausreicht, um Sie davon abzuhalten, das Kernproblem zu sehen und / oder zu beheben. Sobald Sie dieses echte Problem behoben haben, ist die Lesbarkeit des verwendeten Codesauto
im Allgemeinen in Ordnung.Ich nehme fairerweise an, ich sollte hinzufügen: Ich habe einige Fälle behandelt, in denen solche Dinge bei weitem nicht so offensichtlich waren, wie Sie möchten, und das Problem zu beheben war auch ziemlich unhaltbar. Zum Beispiel habe ich vor ein paar Jahren eine Beratung für ein Unternehmen durchgeführt, das zuvor mit einem anderen Unternehmen fusioniert war. Sie endeten mit einer Codebasis, die mehr "zusammengeschoben" als wirklich zusammengeführt wurde. Die konstituierenden Programme hatten damit begonnen, verschiedene (aber recht ähnliche) Bibliotheken für ähnliche Zwecke zu verwenden, und obwohl sie daran arbeiteten, die Dinge sauberer zusammenzuführen, taten sie dies immer noch. In einer ganzen Reihe von Fällen war die einzige Möglichkeit, zu erraten, welcher Typ von einer bestimmten Funktion zurückgegeben wurde, zu wissen, wo diese Funktion entstanden war.
Selbst in einem solchen Fall können Sie dazu beitragen, einige Dinge klarer zu machen. In diesem Fall begann der gesamte Code im globalen Namespace. Das einfache Verschieben einer angemessenen Menge in einige Namespaces beseitigte die Namenskonflikte und erleichterte auch das Typ-Tracking.
quelle
Es gibt mehrere Gründe, warum ich Auto für den allgemeinen Gebrauch nicht mag:
Aber warte, ist das wirklich eine gute Idee? Was wäre, wenn der Typ in einem halben Dutzend dieser Anwendungsfälle eine Rolle spielen würde und sich dieser Code nun tatsächlich anders verhält? Dies kann auch implizit die Kapselung unterbrechen, indem nicht nur die Eingabewerte, sondern auch das Verhalten der privaten Implementierung anderer Klassen, die die Funktion aufrufen, geändert werden.
1a. Ich glaube an das Konzept des "selbstdokumentierenden Codes". Der Grund für den selbstdokumentierenden Code ist, dass Kommentare dazu neigen, nicht mehr aktuell zu sein, was der Code tut, während der Code selbst - wenn er explizit geschrieben ist - selbsterklärend ist und immer auf dem neuesten Stand bleibt auf seine Absicht und wird Sie nicht mit abgestandenen Kommentaren verwechseln lassen. Wenn Typen geändert werden können, ohne dass der Code selbst geändert werden muss, können der Code / die Variablen selbst veralten. Zum Beispiel:
auto bThreadOK = CheckThreadHealth ();
Das Problem besteht jedoch darin, dass CheckThreadHealth () zu einem bestimmten Zeitpunkt überarbeitet wurde, um anstelle eines Bools einen Aufzählungswert zurückzugeben, der den Fehlerstatus angibt, sofern vorhanden. Die Person, die diese Änderung vorgenommen hat, hat es jedoch versäumt, diese bestimmte Codezeile zu überprüfen, und der Compiler war nicht hilfreich, da er ohne Warnungen oder Fehler kompiliert wurde.
Es funktioniert wahrscheinlich sogar irgendwie. Ich sage Art von Arbeit, denn obwohl Sie eine Kopie einer 500-Byte-Struktur für jede Schleifeniteration erstellen, können Sie einen einzelnen Wert darauf überprüfen, der Code ist dennoch voll funktionsfähig. Selbst Ihre Komponententests helfen Ihnen nicht zu erkennen, dass sich hinter diesem einfachen und unschuldig aussehenden Auto schlechter Code verbirgt. Die meisten anderen Personen, die die Datei durchsuchen, bemerken dies auch nicht auf den ersten Blick.
Dies kann auch noch schlimmer gemacht werden, wenn Sie den Typ nicht kennen, aber einen Variablennamen wählen, der eine falsche Annahme darüber macht, was er ist, und tatsächlich dasselbe Ergebnis wie in 1a erzielt, jedoch nicht von Anfang an Post-Refactor.
Es scheint mir offensichtlich, dass auto in erster Linie als Problemumgehung für schreckliche Syntax mit Standardvorlagentypen für Bibliotheken eingeführt wurde. Anstatt zu versuchen, die Schablonensyntax zu korrigieren, mit der die Benutzer bereits vertraut sind - was aufgrund des vorhandenen Codes, der möglicherweise beschädigt wird, auch fast unmöglich ist -, fügen Sie ein Schlüsselwort hinzu, das das Problem im Grunde verbirgt. Im Wesentlichen, was man als "Hack" bezeichnen könnte.
Ich bin mit der Verwendung von auto für Standard-Bibliothekscontainer eigentlich nicht einverstanden. Es ist offensichtlich, wofür das Schlüsselwort erstellt wurde, und es ist unwahrscheinlich, dass Funktionen in der Standardbibliothek ihren Zweck (oder Typ) grundlegend ändern, was die Verwendung von auto relativ sicher macht. Ich wäre jedoch sehr vorsichtig, wenn ich es mit Ihrem eigenen Code und Ihren Schnittstellen verwenden würde, die möglicherweise sehr viel unbeständiger sind und möglicherweise grundlegenderen Änderungen unterliegen.
Eine weitere nützliche Anwendung von auto, mit der die Sprachfunktionen verbessert werden, ist das Erstellen von Temporären in typunabhängigen Makros. Das ist etwas, was du vorher nicht wirklich tun konntest, aber du kannst es jetzt tun.
quelle
auto something = std::make_shared<TypeWithLongName<SomeParam>>(a,b,c);
. :-)Ja, es macht es einfacher, den Typ Ihrer Variablen zu kennen, wenn Sie ihn nicht verwenden
auto
. Die Frage ist: Haben Sie müssen den Typ Ihrer Variablen kennen , den Code zu lesen? Manchmal lautet die Antwort ja, manchmal nein. Wenn Sie beispielsweise einen Iterator von einem abrufenstd::vector<int>
, müssen Sie wissen, dass dies einstd::vector<int>::iterator
oderauto iterator = ...;
ausreichend ist? Alles, was jemand mit einem Iterator machen möchte, ist durch die Tatsache gegeben, dass es sich um einen Iterator handelt - es spielt nur keine Rolle, um welchen Typ es sich handelt.Verwenden
auto
Sie diese Option in Situationen, in denen das Lesen des Codes nicht erschwert wird.quelle
Persönlich benutze ich
auto
nur, wenn es für den Programmierer absolut offensichtlich ist, was es ist.Beispiel 1
Beispiel 2
quelle
auto record = myObj.FindRecord(something)
, wäre klar, dass der Variablentyp ein Datensatz war. Oderit
wenn Sie es benennen oder ähnliches, wird deutlich, dass es einen Iterator zurückgibt. Beachten Sie, dass Sie, selbst wenn Sieauto
die Variable nicht verwenden , bei korrekter Benennung nicht zur Deklaration zurückkehren müssen, um den Typ von einer beliebigen Stelle in der Funktion aus zu betrachten . Ich habe meine Ablehnung entfernt, weil das Beispiel jetzt kein vollständiger Strohmann ist, aber ich kaufe das Argument hier immer noch nicht.MyClass::RecordTy record = myObj.FindRecord (something)
Diese Frage erfordert eine Meinung, die von Programmierer zu Programmierer unterschiedlich sein wird, aber ich würde nein sagen. In vielen Fällen kann genau das Gegenteil
auto
dazu beitragen, den Code verständlicher zu machen, indem der Programmierer sich auf die Logik und nicht auf die Minutien konzentriert.Dies gilt insbesondere angesichts komplexer Vorlagentypen. Hier ist ein vereinfachtes & ausgedachtes Beispiel. Was ist leichter zu verstehen?
.. oder...
Einige würden sagen, die zweite ist leichter zu verstehen, andere mögen die erste sagen. Wieder andere könnten sagen, dass eine unbegründete Verwendung von
auto
dazu beitragen kann, die Programmierer, die es verwenden, zu beschönigen, aber das ist eine andere Geschichte.quelle
std::map
Beispiele, zusätzlich mit komplexen Template-Argumenten.map
s verrückte lange Vorlagennamen zu finden . :)for
z. B. wenn Iteratoren im Schleifenkörper ungültig sind und daher vorab oder gar nicht inkrementiert werden müssen.Bisher viele gute Antworten, aber um sich auf die ursprüngliche Frage zu konzentrieren, denke ich, dass Herb in seinen Ratschlägen zu weit geht, um sie
auto
großzügig zu verwenden . Ihr Beispiel ist ein Fall, in dem die Verwendungauto
offensichtlich die Lesbarkeit beeinträchtigt. Einige Leute bestehen darauf, dass es bei modernen IDEs kein Problem gibt, bei denen Sie den Mauszeiger über eine Variable halten und den Typ sehen können, aber ich bin anderer Meinung: Selbst Leute, die immer eine IDE verwenden, müssen manchmal Codeausschnitte isoliert betrachten (denken Sie an Codeüberprüfungen) zum Beispiel) und eine IDE wird nicht helfen.Fazit: Verwenden
auto
Sie diese Option, wenn dies hilfreich ist: Iteratoren in for-Schleifen. Verwenden Sie es nicht, wenn der Leser Schwierigkeiten hat, den Typ herauszufinden.quelle
Ich bin ziemlich überrascht, dass noch niemand darauf hingewiesen hat, dass Auto hilft, wenn es keinen eindeutigen Typ gibt. In diesem Fall umgehen Sie dieses Problem entweder, indem Sie in einer Vorlage ein #define oder ein typedef verwenden, um den tatsächlich verwendbaren Typ zu finden (und dies ist manchmal nicht trivial), oder Sie verwenden einfach auto.
Angenommen, Sie haben eine Funktion, die etwas mit plattformspezifischem Typ zurückgibt:
Würdest du lieber eine Hexe benutzen?
oder einfach nur
Klar, du kannst schreiben
auch irgendwo, tut es aber
eigentlich noch was über xs typ erzählen? Es sagt, es ist das, was von dort zurückgegeben wird, aber es ist genau das, was auto ist. Das ist einfach überflüssig - 'Zeug' wird hier dreimal geschrieben - dies macht es meiner Meinung nach weniger lesbar als die 'Auto'-Version.
quelle
typedef
sie.Die Lesbarkeit ist subjektiv. Sie müssen sich die Situation ansehen und entscheiden, was am besten ist.
Wie Sie bereits betont haben, können lange Deklarationen ohne Auto viel Durcheinander erzeugen. Aber wie Sie auch betont haben, können kurze Deklarationen wertvolle Typinformationen entfernen.
Darüber hinaus möchte ich Folgendes hinzufügen: Achten Sie darauf, dass Sie auf Lesbarkeit und nicht auf Beschreibbarkeit achten. Code, der einfach zu schreiben ist, ist im Allgemeinen nicht einfach zu lesen und umgekehrt. Wenn ich zum Beispiel schreibe, bevorzuge ich auto. Wenn ich lese, vielleicht die längeren Erklärungen.
Dann gibt es Konsistenz; wie wichtig ist dir das Möchten Sie Auto in einigen Teilen und explizite Deklarationen in anderen oder eine durchgängig einheitliche Methode?
quelle
Ich werde den Vorteil von weniger lesbarem Code nutzen und den Programmierer ermutigen, ihn mehr und mehr zu verwenden. Warum? Wenn der Code, der auto verwendet, schwer zu lesen ist, wird es natürlich auch schwierig sein, ihn zu schreiben. Der Programmierer ist gezwungen, den aussagekräftigen Variablennamen zu verwenden , um seine Arbeit zu verbessern.
Vielleicht schreibt der Programmierer am Anfang nicht die aussagekräftigen Variablennamen. Aber irgendwann, während er die Fehler behebt oder in der Codeüberprüfung anderen den Code erklären muss oder in nicht allzu naher Zukunft, wird der Programmierer den Fehler erkennen und verwenden der aussagekräftige Variablenname in Zukunft.
quelle
myComplexDerivedType
, um den fehlenden Typ auszugleichen, der den Code durch die Typwiederholung überfrachtet (überall, wo die Variable verwendet wird) und die Leute dazu verleitet, den Zweck der Variablen in ihrem Namen wegzulassen . Ich habe die Erfahrung gemacht, dass nichts so unproduktiv ist, als aktiv Hindernisse in den Code zu setzen.Ich habe zwei Richtlinien:
Wenn der Typ der Variablen offensichtlich ist, ist das Schreiben mühsam oder die Verwendung von auto schwer zu bestimmen.
Wenn Sie eine bestimmte Konvertierung benötigen oder der Ergebnistyp nicht offensichtlich ist und Verwirrung stiften kann.
quelle
Ja. Es verringert die Ausführlichkeit, aber das übliche Missverständnis ist, dass die Ausführlichkeit die Lesbarkeit verringert. Dies gilt nur, wenn Sie die Lesbarkeit als ästhetisch und nicht als tatsächliche Fähigkeit zur Interpretation von Code betrachten - was durch die Verwendung von auto nicht erhöht wird. In dem am häufigsten zitierten Beispiel, Vektoriteratoren, kann es auf der Oberfläche erscheinen, dass die Verwendung von auto die Lesbarkeit Ihres Codes erhöht. Auf der anderen Seite wissen Sie nicht immer, was das automatische Schlüsselwort Ihnen geben wird. Sie müssen denselben logischen Pfad wie der Compiler einhalten, um diese interne Rekonstruktion durchzuführen, und in vielen Fällen, insbesondere bei Iteratoren, werden Sie die falschen Annahmen treffen.
Am Ende des Tages opfert 'auto' die Lesbarkeit von Code und Klarheit für syntaktische und ästhetische 'Sauberkeit' (was nur notwendig ist, weil Iteratoren eine unnötig verschlungene Syntax haben) und die Fähigkeit, 10 Zeichen weniger in eine bestimmte Zeile einzugeben. Es ist weder das Risiko noch den langfristigen Aufwand wert.
quelle