Wie kann ich sauber angeben, welche Argumente übergeben werden und welche standardmäßig bleiben?

8

Auf Grund dieser Frage : Standardargument in C ++

Angenommen, ich habe eine Funktion wie diese: void f(int p1=1, int p2=2, int p3=3, int p4=4);

Und ich möchte es nur mit einigen der Argumente aufrufen - der Rest sind die Standardwerte.

So etwas würde funktionieren:

%Vor%

Aber es erfordert zu viel Code, um praktisch zu sein.

Gibt es einen besseren Weg, dies zu tun?

    
Pubby 18.11.2011, 06:03
quelle

4 Antworten

11

Verwenden Sie das Benannte Parameter-Idiom (→ FAQ-Link ). .

Die Boost.Parameters-Bibliothek (→ link ) kann diese Aufgabe auch lösen, wird aber durch Code-Ausführlichkeit und stark reduzierte Klarheit bezahlt. Es ist auch im Umgang mit Konstrukteuren mangelhaft. Und es muss natürlich die Boost-Bibliothek installiert sein.

Prost & amp; hth.,

    
Cheers and hth. - Alf 18.11.2011, 07:15
quelle
7

Sehen Sie sich die Boost.Parameter Bibliothek an .

Es implementiert benannte Parameter in C ++. Beispiel:

%Vor%     
Mankarse 18.11.2011 06:13
quelle
4

Obwohl Boost.Parameters amüsant ist, leidet es (leider) unter einer Reihe von Problemen, unter anderem der Platzhalter-Kollision (und um skurrile Präprozessoren / Template-Fehler zu debuggen):

%Vor%

Erstellt den Platzhalter _p1 , den Sie später verwenden. Wenn Sie zwei verschiedene Header haben, die denselben Platzhalter deklarieren, erhalten Sie einen Konflikt. Nicht lustig.

Es gibt eine viel einfachere (sowohl konzeptionell als auch praktisch) Antwort, basierend auf dem Builder Muster ist etwas Named Parameters Idiom .

Anstatt eine solche Funktion anzugeben:

%Vor%

Sie geben eine Struktur an, in der Sie operator() :

überschreiben
  • Der Konstruktor wird verwendet, um nach obligatorischen Argumenten zu fragen (nicht strikt in der Named Parameters Idiom, aber niemand hat gesagt, dass Sie blind folgen müssen), und Standardwerte sind für die optionalen gesetzt
  • Jeder optionale Parameter erhält einen Setter

Im Allgemeinen wird es mit Verkettung kombiniert, was darin besteht, dass die Setter einen Verweis auf das aktuelle Objekt zurückgeben, so dass die Aufrufe in einer einzigen Zeile verkettet werden können.

%Vor%

Der Aufruf lautet:

%Vor%

Ich habe eine Variante gesehen, bei der die obligatorischen Argumente als Parameter für operator() verwendet wurden. Dadurch wird vermieden, dass die Argumente als Attribute beibehalten werden, aber die Syntax ist etwas seltsamer:

%Vor%

Sobald der Compiler alle Konstruktor- und Setter-Aufrufe inlineiert hat (weshalb sie hier definiert sind, während operator() dies nicht ist), sollte dies zu ähnlich effizientem Code im Vergleich zum "normalen" Funktionsaufruf führen.

    
Matthieu M. 18.11.2011 07:39
quelle
2

Das ist nicht wirklich eine Antwort, aber ...

In C ++ Template-Metaprogrammierung von David Abrahams und Aleksey Gurtovoy (erschienen 2004!) Autoren sprechen darüber:

  

Während wir dieses Buch geschrieben haben, haben wir die Benutzeroberfläche von named überarbeitet   Funktionsparameterunterstützung. Mit ein wenig experimentieren wir   entdeckt, dass es möglich ist, die ideale Syntax durch Verwendung bereitzustellen   Schlüsselwortobjekte mit überladenen Zuweisungsoperatoren:

%Vor%

Sie fahren fort zu sagen:

  

Wir werden uns nicht mit den Einzelheiten dieser Implementierung befassen   Parameterbibliothek hier; es ist einfach genug, dass wir vorschlagen   Sie versuchen, es selbst als Übung zu implementieren.

Dies war im Kontext von Template-Metaprogrammierung und Boost :: MPL. Ich bin mir nicht sicher, wie ihre "Straighforward" -Implementierung mit Standardparametern funktionieren würde, aber ich gehe davon aus, dass sie transparent wäre.

    
Keith Layne 18.11.2011 07:23
quelle