Domanda

Al momento sto lavorando su ripulire un API completa di modelli di funzione, e aveva un forte desiderio di scrivere il codice seguente.

template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);

Quando invoco questo modello, mi piacerebbe farlo nel modo seguente.

std::string text("hello");
doWork(100, 20.0, &text);
doWork('a', text);         // oops!
doWork<char, std::string, void>('a', text);  // to verbose!

Purtroppo, la seconda invocazione non viene compilato in quanto il compilatore non può dedurre il tipo di parametro opzionale. Questo è un peccato, dal momento che davvero non mi interessa quello che il tipo di parametro è, ma piuttosto che il suo valore è NULL. Inoltre, mi piacerebbe evitare il percorso della terza invocazione in quanto ostacola la leggibilità.

Questo mi ha portato a cercare di rendere l'argomento modello V ha un tipo di default, che anche non funziona in quanto non è possibile applicare un tipo predefinito per un argomento modello di funzione (almeno utilizzando VC ++ 9.0).

template <typename T, typename U, typename V = void>  // oops!
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);

La mia unica opzione rimanente è quello di introdurre un sovraccarico di doWork che non sa nulla del V template argomento.

template <typename T, typename U>
void doWork(const T& arg1, const U& arg2)
{
    doWork(arg1, arg2, 0);
}

template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg);

E 'questo l'approccio migliore per risolvere questo problema? L'unico svantaggio che vedo è che ho potuto potenzialmente introdurre molte funzioni di inoltro banali se un modello di funzione contiene molti parametri che hanno valori predefiniti adatti.

È stato utile?

Soluzione

Credo che la funzione di inoltro è una soluzione perfettamente adeguata, anche se nella soluzione, non è necessario specificare in modo esplicito i parametri del modello? (0 è una costante intera che può essere convertita a qualsiasi tipo V*.) doWord Inoltre vs doWork?

Come regola generale, cercare di evitare di parametri opzionali in cui non hanno una forte pay-off.

potrebbe essere più facile da forzare i client di voi funzione per aggiungere solo un , (void*)0 se appriopriate che aggiungere a molto meccanismo di più per supportare sia un parametro di due e una versione a tre parametri del modello. Dipende gli usi previsti, però.

Altri suggerimenti

Dal punto di vista del codice del client, se non ha un terzo parametro, Perché ha bisogno di inventare uno?

Quindi, se si mira per l'usabilità e la leggibilità, sono d'accordo con il metodo di involucro: ha perfettamente senso, e l'involucro si ha scritto è responsabile per un valore discreto del terzo parametro voi reso necessaria.

In cima a quello, rende possibile l'utilizzo di un default diverso per le diverse specializzazioni, se necessario.

Una possibilità è quella di riordinare gli argomenti di template, in modo da quella facoltativa viene prima.

template <typename V, typename T, typename U>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);

doWork<void>('a', text); 

Spedizioni sembra OK troppo.

Ma sembra argomenti e modelli predefiniti non corrispondono bene, però.

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