2011-02-07 34 views
5

Sto cercando di creare un wrapper del C++ attorno a una vecchia API C che utilizza un tipo di dati opaco. C'è una particolare funzione C che prende una stringa di formato, insieme a un numero variabile di argomenti usando le strutture C <stdarg.h>. Come parte del mio wrapper, voglio essere in grado di passare un numero arbitrario di argomenti (inclusi oggetti C++) a questa funzione. Tuttavia, poiché ovviamente le strutture <stdarg.h> non possono funzionare con dati non POD, ho creato una funzione di conversione basata su modelli che converte oggetti C++ (come std::string) in equivalenti POD.Estrazione dell'elenco degli argomenti con il modello Variadic

Ho pensato che tutto questo sarebbe stato un esercizio facile con i modelli variadici C++ 0x, ma ho difficoltà a capire come scrivere questa funzione in modo da srotolare correttamente l'argomento pack mentre si applica la mia funzione di conversione a ogni argomento.

Quello che ho finora è:

template <class T, class... Args> 
    void apply(OPAQUE* object, const char* fmt_string, T&& val, Args&&... args) 
    { 
     apply(object, fmt_string, Convert(val), args...); 
    } 

    template <class... Args> 
    void apply(OPAQUE* object, const char* fmt_string, Args&&... args) 
    { 
     C_API_Function_Call(object, fmt_string, args...); 
    } 

Naturalmente, questo non funziona perché la chiamata di funzione ricorsiva mai effettivamente spacchetta il Args..., in modo che solo fino a quando i recurses overflow dello stack. Non riesco a capire come farlo scompattare gli argomenti mentre anche passando l'argomento corrente alla funzione Convert e quindi passando ricorsivamente lungo il risultato.

Esiste comunque?

risposta

25

Penso che è necessario la stessa sintassi quando si esegue l'inoltro perfetto:

template <class... Args> 
void apply(OPAQUE* object, const char* fmt_string, Args&&... args) 
{ 
    C_API_Function_Call(object, fmt_string, Convert(std::forward<Arg>(args))...); 
} 

I puntini di sospensione ... può essere posizionato in alto a destra di un'espressione che contiene il pacco argomento, e non solo direttamente al diritto del pacchetto di argomenti stesso.

Quindi,:
func (args ...) si espande a func (arg1, arg2, arg3, [...], argN)
func (args) ... si espande a func (arg1), func (arg2), [...], func (argN)

+2

Non so perché l'OP non ha ancora cambiato la sua opinione e ha accettato questa risposta. Quello attualmente accettato è ovviamente sbagliato, e il tuo è corretto. +1 Cheers. –

-1

Al momento la bozza C++ 0x non fornisce alcuna soluzione per questo. Poiché il problema è simile alle tuple in espansione, puoi leggere this discussion e scrivere funzioni di espansione simili.

Problemi correlati