Was sind die Vor- / Nachteile der auto
Schlüsselworts, insbesondere bei for-Schleifen?
for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->something();
}
for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->second->something();
}
for(auto it = x.begin(); it != x.end(); it++ )
{
it->??
}
Wenn Sie nicht wissen, ob Sie einen Iterator für eine Karte oder einen Vektor haben, würden Sie wahrscheinlich nicht wissen, ob Sie ihn verwenden sollen first
second
Eigenschaften des Objekts oder direkt darauf zugreifen sollen, nein?
Dies erinnert mich an die C # -Debatte über die Verwendung des Schlüsselworts var
. Der Eindruck, den ich bisher habe, ist, dass die Leute in der C ++ - Welt bereit sind, das auto
Schlüsselwort mit weniger Kampf als var
in der C # -Welt zu übernehmen. Für mich ist mein erster Instinkt, dass ich gerne den Typ der Variablen kenne, damit ich weiß, welche Operationen ich erwarten kann, um sie auszuführen.
var
? Das habe ich vermisst.for (auto& it : x)
(oder ohne Hinweis, wenn Sie kopieren möchten)x
und Sie nicht einmal wissen, wasx
ist, sollten Sie diese Schleife nicht an erster Stelle schreibenAntworten:
Die Motivationen in C ++ sind extremer, da Typen aufgrund von Metaprogrammierung und anderen Dingen sehr viel komplexer und komplexer werden können als C # -Typen.
auto
ist schneller zu schreiben und zu lesen und flexibler / wartbarer als ein expliziter Typ. Ich meine, möchtest du anfangen zu tippen?Das ist nicht mal der volle Typ. Ich habe ein paar Template-Argumente verpasst.
quelle
auto
für. Von Entwurf.typedef
hilft,auto
hilft aber mehr.In deinem Beispiel:
es muss eine deklaration für
x
sichtbar geben. Daher sollte die Art derit
offensichtlich sein. Wenn der Typx
nicht offensichtlich ist, ist die Methode zu lang oder die Klasse zu groß.quelle
x
ein sehr falscher Variablenname für einen Container. In einigen Situationen können Sie sich wahrscheinlich nur den (semantisch wertvollen) Namen ansehen und die möglichen Operationen ableiten.x
als generisches Beispiel verwendet, neige ich dazu, ziemlich beschreibende Variablennamen zu verwenden.Einspruch ! Geladene Frage.
Können Sie mir erklären, warum der dritte Code enthalten ist
??
, der erste und der zweite jedoch nicht? Der Fairness halber, Ihr Code muss lesen folgt als:Dort. Das gleiche Problem, obwohl Sie es nicht benutzt haben
auto
.In allen Fällen ist die Antwort dieselbe: Der Kontext ist wichtig . Sie können nicht sinnvoll isoliert über ein Stück Code sprechen. Selbst wenn Sie keine Vorlagen, sondern einen konkreten Typ verwendet hätten, hätte dies das Problem nur an eine andere Stelle verschoben, da der Leser Ihres Codes über die Deklaration dieses Typs Bescheid wissen müsste.
Bei Verwendung von
auto
in diesen Situationen Ihren Code unleserlich macht, sollten Sie dies als Warnzeichen dafür behandeln, dass etwas mit Ihrem Code-Design nicht stimmt. Natürlich gibt es Fälle, in denen Details auf niedriger Ebene von Bedeutung sind (z. B. bei Bitoperationen oder älteren APIs). In diesen Fällen kann ein expliziter Typ die Lesbarkeit verbessern. Aber im Allgemeinen - nein.In Bezug auf
var
(da Sie es ausdrücklich erwähnt haben), gibt es auch einen großen Konsens in der C # -Community für die Verwendungvar
. Argumente gegen seine Verwendung beruhen im Allgemeinen auf Irrtümern .quelle
T
ist für den Benutzer so undurchsichtig wieauto
. Trotzdem soll der eine in Ordnung sein und der andere nicht ?! Das ergibt keinen Sinn. Im Falle von OPT
handelt es sich um eine Vertretung für einen beliebigen Typ. In echtem Code kann es sich um die Verwendung von Vorlagen(for typename std::vector<T>::iterator…)
oder einer Klassenschnittstelle handeln. In beiden Fällen ist der tatsächliche Typ vor dem Benutzer verborgen, und dennoch schreiben wir diesen Code routinemäßig ohne Probleme.auto
. Es ist trivial zu sehen, welche Operationenx
vom Kontext unterstützt werden. Tatsächlich gibt Ihnen der Typ keine zusätzlichen Informationen: In beiden Fällen benötigen Sie eine sekundäre (IDE, Dokumentation, Kenntnisse / Speicher), um die unterstützten Vorgänge anzuzeigen.begin
kehrt aber Sie tun wissen , wasstd::vector<>::iterator
ist. Und Sie müssen ein schlechtes Programmiertool verwenden, das Ihnen diese Informationen nicht trivial liefern kann. Das ist sehr verworren. In der Realität kennen Sie entweder beidebegin
und /iterator
oder keine und sollten eine IDE oder einen Editor verwenden, mit dem Sie die relevanten Informationen problemlos zur Verfügung stellen können. Das kann jeder moderne IDE- und Programmiereditor.PROFI
Dein Code :
wird wegen des vorlagenabhängigen Namens nicht kompiliert.
Dies ist die korrekte Syntax:
Nun schauen Sie, wie lang die Typdeklaration ist. Hier erfahren Sie, warum das
auto
Schlüsselwort eingeführt wurde. Dies :ist prägnanter. Das ist also ein Profi.
CON
Du musst ein bisschen vorsichtig sein. Mit dem Schlüsselwort erhalten
auto
Sie den Typ, den Sie deklariert haben.Beispielsweise :
vs
Zum Schluss: Ja, Sie sollten es, aber nicht überbeanspruchen. Einige Leute neigen dazu, es zu oft zu benutzen und setzen auto überall ein, wie im nächsten Beispiel:
vs
quelle
auto i = 0
. Schuldig. Ich mach das. Aber das liegt daran, dass ich weiß, dass0
das ein typisches Wort istint
. (und eine oktale Konstante ;-))Ja du solltest!
auto
löscht den Typ nicht; Auch wenn Sie nicht wissen, wasx.begin()
ist, weiß der Compiler Bescheid und meldet einen Fehler, wenn Sie versuchen, den Typ falsch zu verwenden. Es ist auch nicht ungewöhnlich,map
mit a zu emulierenvector<pair<Key,Value>>
, sodass der verwendete Codeauto
für beide Wörterbuchdarstellungen funktioniert.quelle
Ja, Sie sollten
auto
als Standardregel verwenden. Es hat Vorteile gegenüber der expliziten Angabe des Typs:Hier haben Sie die Wahl. Es gibt auch Fälle, in denen Sie keine Wahl haben:
Vorausgesetzt, Sie wissen genau, was Sie
auto
tun, hat es keine Nachteile.quelle