2008-10-14 16 views
6

Gibt es eine gute Methode zum Schreiben von C/C++ - Funktionsheadern mit Standardparametern, die Funktionsaufrufe sind?Kann das Ergebnis eines Funktionsaufrufs als Standardparameterwert verwendet werden?

Ich habe einige Header mit der Funktion:

int foo(int x, int y = 0); 

ich in einem großen Code-Basis arbeite, wo viele Funktionen diese Funktion aufrufen und sind abhängig von diesem Standardwert. Dieser Standardwert muss jetzt etwas ändern dynamisch und ich nach einem Weg suchen zu tun:

int foo(int x, int y = bar()); 

Wo bar() ist eine Funktion, die den Standardwert generiert basierend auf einigen Systemparametern. Alternativ würde diese Funktion Prototyp wie folgt aussehen:

int foo(int x, int y = baz.bar()); 

Wo baz eine Funktion zu einem Objekt gehören, ist, die nicht innerhalb der Header-Datei instanziiert hat.

+0

AFAIK das ist relevant für C++ nicht C (C unterstützt keine Standardwerte). – Motti

Antwort

6

Ja. Was du geschrieben hast, funktioniert.

+0

Wirklich? Ich hätte nie gedacht. – Dima

+0

Lol. Ich habe das als offensichtlich falsch abgelehnt, bevor ich es selbst ausprobierte. –

+0

C++ programmiert seit 8 Jahren und wusste das nicht! – Justsalt

1

Es sollte vollkommen gültig sein, eine globale Funktion aufzurufen oder ein globales Objekt in diesem Kontext zu referenzieren, solange sich die Deklaration der Funktion/des Objekts im Gültigkeitsbereich befindet. Es kann oder sollte nicht ratsam sein (in Bezug auf gutes Design), aber es sollte funktionieren.

7

würde ich zwei überladene Funktionen nutzen:

int foo(int x, int y);

int foo(int x){return foo(x,bar);}

Wenn Sie die Weiterleitungsfunktion zu inlined erlauben, dann ist die Leistungseinbuße zu klein Null wahrscheinlich ist. Wenn Sie den Hauptteil in einer Nicht-Header-Datei aus der Reihe halten, können Leistungseinbußen auftreten (die wahrscheinlich gering sind), aber viel mehr Flexibilität bei der Implementierung und eine geringere Kopplung.

+0

Der Vorschlag über überladene Funktionen ist gut, aber der Code in der Anfrage funktioniert wie es ist. – Charlie

6

Was ist los mit dem einfachen Entfernen des optionalen Parameters in der ersten Deklaration und der Bereitstellung einer einzigen Parameterüberlastung?

Ich denke, das ist viel sauberer und flexibler als der Versuch, einen dynamischen Standardwert zu verwenden.

0

Versuchen Sie bar() eine statische Elementfunktion. Dies ermöglicht jedem Teil des Programms, der eine solche statische Klasse im Umfang hat, darauf zuzugreifen. Zum Beispiel:

Klasse Foo { public:

static int bar(); };

Dann würden Sie erklären:

int foo (int x, int y = Foo :: bar());

Wenn Sie andere Objekte benötigen, übergeben Sie stattdessen die Instanz des Objekts.

2

Tangential, aber das sieht für mich so aus, als würde es Abhängigkeitsprobleme auf die Straße bringen. Ich würde mit dem Ansatz von stbuton.myopenid.com gehen.

4

Im Standard, Abschnitt 8.3.6 (Standardargumente), Absatz 5, geben sie ein Beispiel, das genau diesen Ansatz verwendet. Insbesondere wird darauf hingewiesen, dass die Standardargumente Ausdrücken sind, so dass ein Funktionsaufruf gilt, allerdings mit Einschränkungen wie Namenssuche und Typkompatibilität.

In meinem Arbeitsplatz, haben wir gebrauchte Signaturen wie folgt aus:

void An_object::An_object(
    const Foo &a, 
    const Bar &b, 
    const Strategem &s = Default_strategem() 
); 

zu ermöglichen Kunden ein Verhalten in einer Klasse Konstruktor außer Kraft zu setzen. Es war praktisch für bedingtes Verhalten, das sich auf die Leistung eines Übersetzers auswirkte ...

Verwandte Themen