2010-08-17 12 views

Antwort

14

Wenn Sie void func(int a = 0, int b); hatten, wie würden Sie angeben, den Standardparameter beim Aufrufen dieser Funktion zu verwenden?

+6

Ich weiß, dass Sie in C++ nicht können, aber andere Sprachen behandeln das mit 'func (, some_val_for_b)' oder benannten Parametern. –

+1

@Dominic Rodger: für mich sieht das wirklich hässlich aus. – dierre

+2

@Dominic Rodger, gut, C++ nicht. Wenn du willst, kannst du Stroupstroup verklagen: P –

-1

Da in einem Funktionsaufruf in jedem Fall die Nicht-Standardargumente aufgerufen werden müssen. Wenn Sie Ihr Standardargument an den Anfang der Argumentliste setzen, wie sollen Sie sagen, dass Sie das Standardargument oder die anderen Argumente setzen?

+1

Was macht den Anfang einer Liste so fundamental anders als das Ende der Liste? Listen sind symmetrisch! –

+2

Ja, aber stell dir folgendes vor: void func (int a, int b = 0, int c, int d = 0); Was machst du, wenn du func anrufst (1, 2, 3); –

+0

Und welches Ende der Liste ist genau "b"? –

1

Nur um @ tenfours Antwort zu ergänzen. C++ - FAQ Lite hat ein Thema, das named parameters beschreibt und ich denke, dass das Thema Ihr Problem zu einem gewissen Grad anspricht.

5

Weil so die Sprache entworfen wurde.

Eine interessantere Frage wäre: Was sind die Alternativen?

Angenommen, Sie void f(A a = MyA, B b);

  • Platzhalter/leeres Argument haben: f(_, abee) oder f(, abee)
  • benannten Argumente (wie in Python): f(b = abee)

Aber das sind Spitzfindigkeiten und schon gar nicht notwendig, denn Im Gegensatz zu Python unterstützt C++ das Überladen von Funktionen:

  • void f(A a, B b);
  • void f(B b) { f(MyA, b); }

und damit die Standardargumente sind nicht erforderlich ... besonders wenn man bedenkt, dass es Probleme gibt, wenn sie mit OO-Code verwendet, da Standardargumente statisch aufgelöst (kompilieren Zeit)

struct Base 
{ 
    virtual void func(int g = 3); 
}; 

struct Derived 
{ 
    virtual void func(int g = 4); 
}; 

int main(int argc, char* argv[]) 
{ 
    Derived d; 
    d.func(); // Derived::func invoked with g == 4 

    Base& b = d; 
    b.func(); // Derived::func invoked with g == 3 (AH !!) 
} 

EDIT: auf benannte Parameter ->

Die Feature kann mit Funktionsobjekten emuliert werden.

class Func 
{ 
public: 
    Func(B b): mA(MyA), mB(b) {} 

    A& a(A a) { mA = a; } 
    B& b(B b) { mB = b; } 

    void operator()() { func(mA, mB); } 
private: 
    A mA; 
    B mB; 
}; 

int main(int argc, char* argv[]) 
{ 
    A a; B b; 
    Func(b)(); 
    Func(b).a(a)(); 
} 

Falls Sie nicht wollen, um die Argumente zu kopieren, haben Sie die Möglichkeit, Referenzen/Zeiger zu verwenden, obwohl es kompliziert werden kann.

Es ist ein handliches Idiom, wenn Sie eine Vielzahl von Standardeinstellungen ohne echte Reihenfolge der Priorität haben.

+0

Das Überladen der Funktion hilft nicht, wenn 'A' und' B' beide vom selben Typ sind ... –

+0

@Oli: Warum? Wenn man den ersten "func" -Prototyp angibt, ist klar, dass wenn nur ein Parameter vorhanden ist, der Standardwert für den ersten Parameter unabhängig von seinem Typ verwendet werden soll. Dinge werden haarig, wenn Sie zwei Standard haben;) Im Allgemeinen sind benannte Parameter das einzige Ding, das das Problem lösen konnte, und was groß ist, ist, dass sie eine Kompilierungszeitlösung sind. –

+0

Ja, Sie haben Recht. Ich dachte, du benutzt das Überladen, um 'func (A a, B b)', 'func (B b)' * und * 'func (A a)' zu disambiguieren. –

Verwandte Themen