Wie viel ist zu viel mit dem C++11-Auto-Schlüsselwort?

Lesezeit: 12 Minuten

Wie viel ist zu viel mit dem C11 Auto Schlusselwort
Alan Turing

Ich habe die neue verwendet auto Schlüsselwort, das im C++11-Standard für komplizierte Vorlagentypen verfügbar ist, wofür es meines Erachtens entwickelt wurde. Aber ich benutze es auch für Dinge wie:

auto foo = std::make_shared<Foo>();

Und skeptischer für:

auto foo = bla(); // where bla() return a shared_ptr<Foo>

Ich habe nicht viele Diskussionen zu diesem Thema gesehen. Es scheint, dass auto könnte überbeansprucht werden, da ein Typ oft eine Form der Dokumentation und Plausibilitätsprüfung ist. Wo ziehen Sie die Grenze bei der Verwendung auto und was sind die empfohlenen Anwendungsfälle für diese neue Funktion?

Zur Klarstellung: Ich bitte nicht um eine philosophische Meinung; Ich bitte um die bestimmungsgemäße Verwendung dieses Schlüsselworts durch das Standardkomitee, möglicherweise mit Kommentaren dazu, wie diese bestimmungsgemäße Verwendung in der Praxis realisiert wird.

  • @heishe, ich habe eine Klarstellung hinzugefügt. Wenn Sie die Frage sehr allgemein lesen, scheint es eine subjektive Meinung zu sein, aber wirklich, wenn Sie die verwendet haben auto Stichwort, dann wissen Sie, wie es ist soll verwendet werden. Das ist, was ich frage, als jemand, der neu in dieser Funktion ist, wie soll ich es benutzen?

    – Alan Turing

    22. Juni 2011 um 4:50 Uhr

  • Ich habe diese Diskussion überall gesehen, als C# eingeführt wurde var (das heißt, sobald die Leute über die Idee hinweggekommen waren, dass es doch keine dynamische Eingabe war). Wenn Sie möchten, können Sie mit dieser Frage beginnen und die zugehörigen Fragen durchgehen.

    – R.Martinho Fernandes

    22. Juni 2011 um 5:11 Uhr


  • @ildjarn, es tut mir leid, dass du so denkst. Die Antwort, die ich gewählt habe, listet klare Codeausschnitte mit guten und schlechten Verwendungen auf auto. Nicht alle Fragen fragen, was 2+2 ist. Zum Beispiel ist die Frage, WIE ich 2+2 berechne, immer noch eine gute Frage, aber man könnte sie leicht “subjektiv” nennen. Vielleicht bin ich naiv, aber zu mir, wenn eine Frage zu einem führt sinnvoll Klärende Antwort, dann verdienen sowohl die Frage als auch die Antwort auf der Website zu sein.

    – Alan Turing

    22. Juni 2011 um 20:43 Uhr


  • @Lex: Entweder etwas ist legal oder es ist nicht; etwas „Schlechtes“ zu nennen, das legal ist, ist per definitionem subjektiv. Dh anrufen auto foo = bla(); “schlecht” ist eindeutig eine Meinung, keine Tatsache, die diese Frage und Antwort zu einer Diskussion macht, die sie für Programmers SE relevant macht, was genau die engen Stimmen anzeigen. /zucken

    – Ildjarn

    22. Juni 2011 um 22:22 Uhr

  • Herb Sutters Ansicht zu dieser Angelegenheit: herbutter.com/2013/06/13/…

    – Rafak

    15. Juni 2013 um 12:18 Uhr

Wie viel ist zu viel mit dem C11 Auto Schlusselwort
Kirill V. Ljadwinski

Ich denke, dass man das nutzen sollte auto Schlüsselwort immer dann, wenn es auf den ersten Blick schwer zu sagen ist, wie man den Typ schreibt, aber der Typ auf der rechten Seite eines Ausdrucks offensichtlich ist. Zum Beispiel mit:

my_multi_type::nth_index<2>::type::key_type::composite_key_type::
    key_extractor_tuple::tail_type::head_type::result_type

Um den zusammengesetzten Schlüssel zu erhalten, geben Sie ihn ein boost::multi_indexobwohl Sie wissen, dass es so ist int. Du kannst nicht einfach schreiben int weil es in Zukunft geändert werden könnte. ich würde schreiben auto in diesem Fall.

Also wenn die auto Schlüsselwort verbessert die Lesbarkeit in einem bestimmten Fall, dann verwenden Sie es. Du kannst schreiben auto wenn es für den Leser offensichtlich ist, welche Art auto repräsentiert.

Hier sind einige Beispiele:

auto foo = std::make_shared<Foo>();   // obvious
auto foo = bla();                     // unclear. don't know which type `foo` has

const size_t max_size = 100;
for ( auto x = max_size; x > 0; --x ) // unclear. could lead to the errors
                                      // since max_size is unsigned

std::vector<some_class> v;
for ( auto it = v.begin(); it != v.end(); ++it )
                                      // ok, since I know that `it` has an iterator type
                                      // (don't really care which one in this context)

  • Das scheint keine sehr gute Empfehlung zu sein. Wie oft kennen Sie die Art des Objekts nicht? (Das heißt, außerhalb von Vorlagen.) Und wenn Sie nicht wissen, dass sie tippen, schlagen Sie nach, seien Sie nicht faul und verwenden Sie auto.

    – Paul Manta

    22. Juni 2011 um 5:00 Uhr

  • @Paul: oft wissen oder müssen Sie nur den wichtigsten Teil des Typs kennen, zB dass es sich um einen Iterator handelt, aber Sie wissen nicht und es ist Ihnen egal, ob es sich um einen Iterator von Vektoren oder einen Iterator von verknüpften handelt Liste; In diesen Fällen möchten Sie wirklich keine Zeit und keinen Platz auf dem Bildschirm verschwenden, um herauszufinden, wie Sie die Typen aufschreiben.

    – Lüge Ryan

    22. Juni 2011 um 12:58 Uhr

  • Ob C++-Diehards es mögen oder nicht, C++0x wird Leute anziehen, die C++ nie benutzt hätten. Und diese werden überall Auto verwenden.

    – Prof. Falken

    22. Juni 2011 um 13:02 Uhr

  • @R.MartinhoFernandes – nein, das einzige, was klar ist, ist das wie auch immer bla() Rückgaben, denen Sie es geben foo.

    – Luis Machuca

    1. Oktober 2013 um 20:35 Uhr

  • @LuisMachuca Meine Antwort war eine augenzwinkernde Art zu sagen, dass es unehrlich ist, ein Lehrbuchbeispiel für schlechte Variablen- und Funktionsbenennung zu geben und die mangelnde Lesbarkeit auf die Typinferenz zurückzuführen.

    – R.Martinho Fernandes

    1. Oktober 2013 um 22:03 Uhr


Wie viel ist zu viel mit dem C11 Auto Schlusselwort
Jon Purdy

Verwenden auto wo immer Sie können – besonders const auto damit Nebenwirkungen weniger besorgniserregend sind. Sie müssen sich außer in den offensichtlichen Fällen keine Gedanken über Typen machen, aber sie werden trotzdem statisch für Sie verifiziert, und Sie können einige Wiederholungen vermeiden. Woher auto nicht machbar ist, können Sie verwenden decltype um Typen semantisch auszudrücken als Verträge basierend auf Ausdrücken. Ihr Code wird anders aussehen, aber es wird eine positive Änderung sein.

  • Ich würde besonders ‘const auto&’ sagen

    – Viktor Sehr

    22. August 2013 um 8:15 Uhr

  • Besser verwenden auto&& in komplexen Situationen edmundv.home.xs4all.nl/blog/2014/01/28/…

    – KindDragon

    6. März 2014 um 15:56 Uhr

  • @KindDragon: Das ist eine gute Faustregel, aber ich ziehe es vor, sie zu verwenden const auto& oder const auto es sei denn, ich möchte explizit mutieren oder mich bewegen.

    – Jon Purdy

    6. März 2014 um 18:15 Uhr

  • Wenn Sie überall auto verwenden, wird Ihr Code weniger lesbar und schwieriger zu debuggen, da Sie die Typen beim Lesen des Codes selbst ableiten müssen.

    – Untermaschine

    7. Juli 2019 um 8:14 Uhr

  • @Young Ich sage nicht, dass Sie es nicht verwenden sollten, ich sage, Sie sollten klug damit umgehen – verwenden Sie auto, wo immer Sie glauben, dass es die Lesbarkeit des Codes verbessert, und vermeiden Sie es, wo immer es die Absicht des Codes verdeckt. “Richtige” IDEs stehen Ihnen nicht immer zur Verfügung, und selbst wenn dies der Fall ist, ist es weniger bequem, den Mauszeiger über Variablen zu bewegen, um ihre Typen zu erhalten, als nur die Typen als Teil des Codes zu sehen.

    – Untermaschine

    21. August 2020 um 8:50 Uhr

1646784615 672 Wie viel ist zu viel mit dem C11 Auto Schlusselwort
Spraff

Leicht. Verwenden Sie es, wenn Sie egal was für ein typ ist. Zum Beispiel

for (const auto & i : some_container) {
   ...

Mir geht es hier nur darum i ist, was auch immer in dem Container ist.

Es ist ein bisschen wie Typedefs.

typedef float Height;
typedef double Weight;
//....
Height h;
Weight w;

Hier ist es mir egal, ob h und w Floats oder Doubles sind, nur dass sie es sind welcher Typ geeignet ist, um Höhen und Gewichte auszudrücken.

Oder überlegen

for (auto i = some_container .begin (); ...

Hier ist mir nur wichtig, dass es ein geeigneter Iterator ist, der unterstützt operator++()es ist in dieser Hinsicht so etwas wie Ententypisierung.

Auch die Art der Lambdas kann nicht buchstabiert werden auto f = []... ist guter Stil. Die Alternative ist Casting zu std::function aber das kommt mit Overhead.

Ich kann mir einen “Missbrauch” nicht wirklich vorstellen auto. Am ehesten kann ich mir vorstellen, dass Sie sich einer expliziten Konvertierung in einen signifikanten Typ berauben – aber Sie würden es nicht verwenden auto Dafür würden Sie ein Objekt des gewünschten Typs konstruieren.

Wenn du kann Entfernen Sie etwas Redundanz in Ihrem Code, ohne Nebenwirkungen einzuführen, und dann Muss sei gut dabei.

Gegenbeispiele (aus den Antworten von jemand anderem übernommen):

auto i = SomeClass();
for (auto x = make_unsigned (y); ...)

Hier kümmern wir uns um den Typ, also sollten wir schreiben Someclass i; und for(unsigned x = y;...

  • Wenn Sie sich nicht um den Typ kümmern, sollte er für die generische Programmierung als Vorlage verwendet werden

    – Benutzer997112

    26. September 2020 um 1:30 Uhr

  • @ user997112 Seit C ++ 20 ist die auto Schlüsselwort kann verwendet werden, um Parametertypen in Funktionsvorlagen abzuleiten.

    – Anderson Green

    3. September 2021 um 15:04 Uhr

1646784615 463 Wie viel ist zu viel mit dem C11 Auto Schlusselwort
DarenW

Tue es. Verwenden auto Überall macht es das Schreiben von Code einfacher.

Jede neue Funktion in jeder Sprache wird zumindest von einigen Arten von Programmierern überstrapaziert. Nur durch moderate Überbeanspruchung durch einige erfahrene Programmierer (keine Noobs) lernen die übrigen erfahrenen Programmierer die Grenzen des richtigen Gebrauchs kennen. Extreme Überbeanspruchung ist normalerweise schlecht, könnte aber gut sein, da eine solche Überbeanspruchung zu Verbesserungen der Funktion oder einer besseren Funktion führen kann, um sie zu ersetzen.

Aber wenn ich an Code mit mehr als ein paar Zeilen wie z

auto foo = bla();

Wo der Typ null Mal angegeben ist, möchte ich diese Zeilen möglicherweise so ändern, dass sie Typen enthalten. Das erste Beispiel ist großartig, da der Typ einmal angegeben wird, und auto erspart uns das zweimalige Schreiben unordentlicher Vorlagentypen. Hurra für C++++. Aber das explizite Zeigen des Typs Null mal, wenn es nicht leicht in einer nahe gelegenen Zeile sichtbar ist, macht mich nervös, zumindest in C++ und seinen unmittelbaren Nachfolgern. Für andere Sprachen, die entwickelt wurden, um auf einer höheren Ebene mit mehr Abstraktion, Polymorphismus und Generizität zu arbeiten, ist es in Ordnung.

1646784615 532 Wie viel ist zu viel mit dem C11 Auto Schlusselwort
Sean

Bei C++ und darüber hinaus 2012 in dem Fragen Sie uns alles Panel, es gab eine fantastischer Austausch zwischen Andrei Alexandrescu, Scott Meyers und Herb Sutter, in dem es darum ging, wann man es benutzt und wann nicht auto. Springen Sie zu Minute 25:03 für eine 4-minütige Diskussion. Alle drei Redner geben hervorragende Punkte, die man im Hinterkopf behalten sollte nicht verwenden auto.

Ich ermutige die Leute sehr, zu ihren eigenen Schlussfolgerungen zu kommen, aber mein Fazit war es verwenden auto überall, überallhin, allerorts wenn nicht:

  1. Es schadet der Lesbarkeit
  2. Es bestehen Bedenken hinsichtlich der automatischen Typkonvertierung (z. B. von Konstruktoren, Zuweisungen, Template-Zwischentypen, implizite Konvertierung zwischen ganzzahligen Breiten).

Großzügiger Gebrauch von explicit hilft, die Sorge um Letzteres zu verringern, was dazu beiträgt, die Zeitdauer zu minimieren, in der Ersteres ein Problem darstellt.

Umformulieren, was Herb sagte: „Wenn Sie X, Y und Z nicht machen, verwenden Sie auto. Erfahren Sie, was X, Y und Z sind, und gehen Sie weiter und verwenden Sie es auto überall sonst.”

  • Wahrscheinlich auch einen Link zu “fast immer automatisch” wert — herbutter.com/2013/08/12/…

    – Rob Starling

    6. April 2016 um 5:56 Uhr

  • Nette Empfehlung … tolles Gespräch. Herb hat meine Meinung geändert auto verwenden.

    – kmiklas

    5. Januar 2021 um 16:43 Uhr

1646784616 958 Wie viel ist zu viel mit dem C11 Auto Schlusselwort
Gene Buschujew

Ja, es kann zu Lasten der Lesbarkeit überstrapaziert werden. Ich schlage vor, es in Kontexten zu verwenden, in denen genaue Typen lang oder unaussprechlich oder für die Lesbarkeit nicht wichtig und Variablen kurzlebig sind. Beispielsweise ist der Iteratortyp normalerweise lang und daher nicht wichtig auto würde funktionieren:

   for(auto i = container.begin(); i != container.end(); ++i);

auto hier tut der Lesbarkeit keinen Abbruch.

Ein weiteres Beispiel ist der Parser-Regeltyp, der lang und verschachtelt sein kann. Vergleichen:

   auto spaces = space & space & space;

mit

r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&> spaces = 
   space & space & space;

Auf der anderen Seite, wenn der Typ bekannt und einfach ist, ist es viel besser, wenn er explizit angegeben wird:

int i = foo();

eher, als

auto i = foo();

  • Wahrscheinlich auch einen Link zu “fast immer automatisch” wert — herbutter.com/2013/08/12/…

    – Rob Starling

    6. April 2016 um 5:56 Uhr

  • Nette Empfehlung … tolles Gespräch. Herb hat meine Meinung geändert auto verwenden.

    – kmiklas

    5. Januar 2021 um 16:43 Uhr

1646784616 285 Wie viel ist zu viel mit dem C11 Auto Schlusselwort
morotspaj

auto kann in Kombination mit Ausdrucksvorlagen, die häufig von Bibliotheken für lineare Algebra wie Eigen oder OpenCV verwendet werden, sehr gefährlich sein.

auto A = Matrix(...);
auto B = Matrix(...);
auto C = A * B; // C is not a matrix. It is a matrix EXPRESSION.
cout << C; // The expression is evaluated and gives the expected result.
... // <code modifying A or B>
cout << C; // The expression is evaluated AGAIN and gives a DIFFERENT result.

Fehler, die durch diese Art von Fehlern verursacht werden, sind ein großer Schmerz beim Debuggen. Eine mögliche Abhilfe besteht darin, das Ergebnis explizit in den erwarteten Typ umzuwandeln, wenn Sie unbedingt auto für den Deklarationsstil von links nach rechts verwenden möchten.

auto C = Matrix(A * B); // The expression is now evaluated immediately.

  • Das scheint zunächst ein seltsames Verhalten zu sein. Wenn ich zwei Matrizen multipliziere, selbst wenn die Operation faul ist, würde ich nicht erwarten, dass sie neu ausgewertet werden kann, ich würde erwarten, dass sie ihren ausgewerteten Zustand nach der anfänglichen Auswertung beibehält. Wenn Sie die Parameter ändern möchten, ohne die ursprünglichen Parameter zu ändern, müssten Sie den Ausdruck dann nicht trotzdem neu erstellen? Oder ist es für eine Art Streaming-Verarbeitung konzipiert, in der sich die ursprünglichen Parameter ständig ändern, der Vorgang jedoch gleich bleibt?

    – JAB

    13. November 2015 um 19:10 Uhr


  • Ob die A*B Ausdruck wird in eine kopiert auto Variable oder etwas anderes, das von Ihnen beschriebene Verhalten ist immer noch vorhanden.

    – xtofl

    20. Januar 2016 um 9:52 Uhr

  • Kein Fehler ist verursacht durch die Nutzung auto.

    – Jim Balter

    26. Januar 2017 um 1:36 Uhr

  • @JAB: Es wurde entwickelt, um beispielsweise Vereinfachungen und Synergien zwischen Operationen zu unterstützen diag(A * B) muss keine Zyklen verschwenden, um die Elemente außerhalb der Diagonale zu berechnen.

    – Ben Voigt

    12. Februar 2018 um 6:23 Uhr


  • Ich habe auch Code wie ‘for (auto o : vecContainer)’ entdeckt, wobei ‘o’ ein schweres Objekt war, das jedes Mal kopiert wird. Meine Empfehlung wäre, es für das zu verwenden, wofür es ursprünglich gedacht war, dh Vorlagen (mit schwierigen Abzugsrichtlinien) und mühsame Typedefs. Selbst dann müssen Sie vorsichtig sein und zwischen auto und auto& unterscheiden.

    – Gast128

    19. Januar 2020 um 12:55 Uhr

978950cookie-checkWie viel ist zu viel mit dem C++11-Auto-Schlüsselwort?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy