Il risultato di una chiamata di funzione può essere utilizzato come valore di parametro predefinito?

StackOverflow https://stackoverflow.com/questions/202718

  •  03-07-2019
  •  | 
  •  

Domanda

Esiste un buon metodo per scrivere intestazioni di funzioni C / C ++ con parametri predefiniti che sono chiamate di funzione?

Ho qualche intestazione con la funzione:

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

Sto lavorando in una grande base di codice in cui molte funzioni chiamano questa funzione e dipendono da questo valore predefinito. Questo valore predefinito ora deve cambiare in qualcosa di dinamico e sto cercando un modo per farlo:

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

Where bar () è una funzione che genera il valore predefinito basato su alcuni parametri di sistema. In alternativa, questo prototipo di funzione sarebbe simile a:

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

Dove baz è una funzione appartenente a un oggetto che non è stato istanziato nel file di intestazione.

È stato utile?

Soluzione

Altri suggerimenti

Vorrei usare due funzioni sovraccaricate:

int foo (int x, int y);

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

Se si consente di inline la funzione di inoltro, è probabile che la penalità di prestazione sia da piccola a zero. Se mantieni il corpo fuori linea in un file non di intestazione, potrebbero esserci costi di prestazione (probabilmente piccoli), ma molta più flessibilità nell'implementazione e riduzione dell'accoppiamento.

Sì. Quello che hai scritto funziona.

Cosa c'è di sbagliato nel rimuovere semplicemente il parametro opzionale nella prima dichiarazione e fornire un sovraccarico di un singolo parametro?

int foo(int x)
{
    Bar bar = //whatever initialization
    return foo(x,bar.baz());
}

int foo(int x,int y)
{
  //whatever the implementation is right now
}

Penso che questo tende ad essere molto più pulito e flessibile rispetto al tentativo di utilizzare un valore predefinito dinamico.

Nella norma, sezione 8.3.6 (Argomenti predefiniti), paragrafo 5, forniscono un esempio usando solo questo approccio. In particolare, afferma che gli argomenti predefiniti sono espressioni , quindi si applica una chiamata di funzione, anche se con restrizioni come la ricerca dei nomi e la compatibilità dei tipi.

Nel mio posto di lavoro, abbiamo usato firme come questa:

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

per consentire ai client di sovrascrivere un comportamento in un costruttore di classi. È stato utile per il comportamento condizionale che ha influito sulle prestazioni di un traduttore ...

Tangenziale, ma mi sembra che introduca problemi di dipendenza lungo la strada. Andrei con l'approccio di stbuton.myopenid.com.

Dovrebbe essere perfettamente valido chiamare una funzione globale o fare riferimento a un oggetto globale in questo contesto, purché la dichiarazione della funzione / oggetto sia nell'ambito. Potrebbe essere consigliabile o meno (in termini di buona progettazione), ma dovrebbe funzionare.

Prova a rendere bar () una funzione membro statica. Ciò consentirà a qualsiasi parte del programma che ha una tale classe statica nell'ambito di accedervi. Ad esempio:

classe Foo { pubblico:

static int bar (); };

Quindi dichiareresti:

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

Se hai bisogno di oggetti diversi, passa invece nell'istanza dell'oggetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top