2010-08-17 22 views

risposta

14

se avessi void func(int a = 0, int b);, come specificheresti di utilizzare il parametro predefinito nel chiamare questa funzione?

+6

So che non è possibile in C++, ma altri linguaggi lo gestiscono con 'func (, some_val_for_b)', o parametri con nome. –

+1

@Dominic Rodger: a me sembra davvero brutto. – dierre

+2

@Dominic Rodger, beh, il C++ no. Se vuoi puoi fare causa a Stroupstroup: P –

-1

Perché in una chiamata di funzione è necessario chiamare gli argomenti non predefiniti in ogni caso. Se metti l'argomento predefinito all'inizio dell'elenco degli argomenti, come dovresti dire che stai impostando l'argomento predefinito o gli altri?

+1

Cos'è che rende l'inizio di una lista così fondamentalmente diversa dalla fine della lista? Le liste sono simmetriche! –

+2

Sì, ma immaginate questo: void func (int a, int b = 0, int c, int d = 0); Cosa stai facendo quando chiami func (1, 2, 3); –

+0

E quale fine della lista, esattamente, è 'b' su? –

1

Solo per integrare la risposta di @ tenfour. Domande frequenti su C++ Lite ha un argomento che descrive named parameters e penso che l'argomento risolva in qualche modo il problema.

5

Perché è così che è stato progettato il linguaggio.

Una domanda più interessante sarebbe: quali sono le alternative?

Supponiamo di avere void f(A a = MyA, B b);

  • Segnaposto/argomento vuoto: f(_, abee) o f(, abee)
  • argomenti con nome (come in Python): f(b = abee)

Ma quelli sono sottigliezze e certamente non necessarie, a causa a differenza di Python C++ supporta l'overloading delle funzioni:

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

e, quindi, gli argomenti di default sono inutili ... soprattutto se si considera che ci sono problemi quando viene utilizzato con OO-codice perché gli argomenti predefiniti sono risolti staticamente (compile-time)

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: su parametri denominati ->

Il la funzione può essere emulata usando gli oggetti funzione.

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)(); 
} 

Nel caso in cui non si desidera copiare gli argomenti, si ha la possibilità di utilizzare i riferimenti/puntatori anche se può complicarsi.

È un pratico idioma quando si hanno un sacco di valori predefiniti senza un vero ordine di priorità.

+0

L'overloading delle funzioni non aiuta se 'A' e' B' sono entrambi dello stesso tipo ... –

+0

@Oli: perché? dato il primo prototipo 'func' è chiaro che se c'è un solo parametro allora il valore di default dovrebbe essere usato per il primo parametro, qualunque sia il loro tipo. Le cose si complicano quando si hanno due impostazioni predefinite;) In generale, i parametri denominati sono l'unica cosa che può risolvere il problema, e ciò che è grande è che sono una soluzione in fase di compilazione. –

+0

Sì, hai ragione. Ho pensato che stavate usando il sovraccarico per disambiguare 'func (A a, B b)', 'func (B b)' * e * 'func (A a)'. –

Problemi correlati