Warum werden nicht benannte Parameter häufiger verwendet?

7

Ich habe eine Parameterklasse entworfen, die es mir erlaubt, einen solchen Code zu schreiben:

%Vor%

Die Leistung der Klasse ist ziemlich schnell: Alles ist nur eine Referenz auf dem Stapel. Und um alle Informationen zu speichern, verwende ich einen internen Puffer von bis zu 5 Argumenten, bevor es zur Heap-Zuweisung geht, um die Größe jedes einzelnen Objekts zu verringern, aber dies kann leicht geändert werden.

Warum wird diese Syntax nicht häufiger verwendet, indem operator,() überladen wird, um benannte Parameter zu implementieren? Liegt es an der potenziellen Leistungseinbuße?

Ein anderer Weg ist das benannte Idiom:

%Vor%

Aber für mich sieht das Überladen von operator,() viel mehr "modernes" C ++ aus, solange Sie nicht vergessen, doppelte Klammern zu verwenden. Die Leistung leidet auch nicht viel, auch wenn sie langsamer als eine normale Funktion ist, so dass sie in den meisten Fällen vernachlässigbar ist.

Ich bin wahrscheinlich nicht der erste, der eine solche Lösung vorschlägt, aber warum ist das nicht häufiger? Ich habe noch nie so etwas wie die obige Syntax gesehen (mein Beispiel), bevor ich eine Klasse geschrieben habe, die es akzeptiert, aber für mich sieht es perfekt aus.

    
Fredrik 05.04.2012, 23:57
quelle

2 Antworten

52
  

Meine Frage ist, warum diese Syntax nicht mehr verwendet wird, um den Operator zu überladen (), um benannte Parameter zu implementieren.

Weil es kontraintuitiv, nicht von Menschen lesbar und wohl eine schlechte Programmierpraxis ist. Wenn Sie die Codebasis nicht sabotieren wollen, sollten Sie dies vermeiden.

%Vor%

Sagen wir, ich sehe dieses Codefragment zum ersten Mal. Mein Denkprozess läuft so:

  1. Auf den ersten Blick sieht es aus wie ein Beispiel für "das ärgste Parsen" , weil Sie doppelte Klammern verwenden. Ich nehme an, dass der Test eine Variable ist und sich fragen muss, ob Sie vergessen haben, den Typ der Variablen zu schreiben. Dann fällt mir auf, dass dieses Ding tatsächlich kompiliert. Danach muss ich mich fragen, ob dies eine Instanz einer sofort zerstörten Klasse von Typtest ist und Sie Kleinbuchstaben für alle Klassen verwenden.
  2. Dann entdecke ich, dass es sich tatsächlich um einen Funktionsaufruf handelt. Großartig.
  3. Das Codefragment sieht jetzt wie ein Funktionsaufruf mit zwei Argumenten aus.
  4. Nun wird mir klar, dass dies kein Funktionsaufruf mit zwei Argumenten sein kann, weil Sie doppelte Klammern verwendet haben.
  5. Also, jetzt muss ich herausfinden, was zum Teufel in () los ist.
  6. Ich erinnere mich, dass es einen Komma-Operator gibt (den ich in den letzten 5 Jahren noch nie in echtem C ++ - Code gesehen habe), der das vorherige Argument verwirft. SO JETZT muss ich mich fragen, was ist dieser nützliche Nebeneffekt von name (), und was der name () ist - ein Funktionsaufruf oder ein Typ (weil Sie nicht Großbuchstaben / Kleinbuchstaben verwenden, um zwischen Klasse / Funktion zu unterscheiden Test ist eine Klasse, aber test ist eine Funktion), und Sie haben C Präfixe nicht.
  7. Nachdem ich im Quellcode nach name gesucht habe, stelle ich fest, dass es sich um eine Klasse handelt. Und es überlädt den Operator , , sodass das erste Argument nicht mehr verwerfen kann.

Sehen Sie, wie viel Zeit hier verschwendet wird? Ehrlich gesagt, können Sie Probleme damit haben, etwas zu schreiben, weil Sie Sprachfunktionen verwenden, um Ihren Code so aussehen zu lassen, als ob Ihr Code tatsächlich etwas anderes tut (Sie machen einen Funktionsaufruf mit einem Argument so, als ob er zwei Argumente oder das hätte es ist eine variadic Funktion). Dies ist eine schlechte Programmierpraxis, die in etwa dem Überladen von Operator + entspricht, um Subtraktionen anstelle von Additionen durchzuführen.

Betrachten wir nun ein Beispiel QString .

%Vor%

Sagen wir, ich sehe es zum ersten Mal in meinem Leben. So geht mein Denkprozess:

  1. Es gibt eine Variable status vom Typ QString.
  2. Es wird von einer temporären Variablen vom Typ QString () initialisiert.
  3. ... nachdem die QString :: arg-Methode aufgerufen wurde. (Ich weiß, es ist eine Methode).
  4. Ich sehe .arg in der Dokumentation nach, um zu sehen, was es tut, und entdecke, dass es %1 -style Einträge ersetzt und QString & amp; zurückgibt. Also macht die Kette von .arg() sofort Sinn. Bitte beachten Sie, dass etwas wie QString :: arg templated sein kann, und Sie können es für verschiedene Argumenttypen aufrufen, ohne den Typ des Arguments in <> .
  5. manuell anzugeben
  6. Dieses Codefragment macht jetzt Sinn, also gehe ich zu einem anderen Fragment über.
  

sieht sehr viel "moderner" C ++ aus.

"New and shiny" bedeutet manchmal "buggy and broken" (Slackware Linux basiert auf einer etwas ähnlichen Idee). Es ist irrelevant, wenn Ihr Code modern aussieht. Es sollte für Menschen lesbar sein, es sollte tun, was es beabsichtigt ist, und Sie sollten die minimal mögliche Zeit verschwenden, um es zu schreiben. I.e. Sie sollten (persönliche Empfehlung) darauf abzielen, "eine maximale Menge an Funktionalität in einer minimalen Zeitmenge zu minimalen Kosten (einschließlich Wartung) zu implementieren", erhalten aber die maximale Belohnung dafür. Es macht auch Sinn, dem KISS-Prinzip zu folgen.

Ihre "moderne" Syntax verringert nicht die Entwicklungskosten, reduziert nicht die Entwicklungszeit und erhöht die Wartungskosten (kontraintuitiv). Daher sollte diese Syntax vermieden werden.

    
SigTerm 06.04.2012, 01:18
quelle
3

Es gibt keine Notwendigkeit. Ihre dynamische Verteilung (je nach logischem -Typ des Arguments kann sich anders verhalten) kann a) viel einfacher und b) viel schneller unter Verwendung der Template-Spezialisierung implementiert werden.

Und wenn Sie tatsächlich eine Unterscheidung aufgrund von Informationen benötigen, die nur zur Laufzeit verfügbar sind, würde ich versuchen, Ihre test -Funktion als virtuelle Methode vom Typ param zu verwenden und einfach dynamisches Binden zu verwenden (das ist es es ist für, und das ist, was Sie neu erfinden).

Die einzigen Fälle, in denen dieser Ansatz sinnvoller wäre, sind Szenarien mit mehreren Absätzen, in denen Sie Code reduzieren und einige Ähnlichkeitsmuster finden möchten.

    
bitmask 06.04.2012 00:12
quelle

Tags und Links