2013-05-08 16 views
8

Nella mia applicazione ho molti registri. Accumulo tutti gli errori di tutti i registri in un'unica posizione denominata errorsLogger. Ho implementato in questo modo:come inoltrare il numero variabile di argomenti in un'altra funzione?

static Logger errorsLogger; 

.... 

void Logger::Error(std::string format, ...) { 
    va_list arglist; 
    va_start(arglist, format); 

    if (this != &errorsLogger) { 
     errorsLogger.Error(format, arglist);  // how to forward parameters? 
    } 

    vfprintf(logFile, , format.c_str(), arglist); 
    fprintf(logFile, "\n"); 

    fflush(logFile); 
    va_end(arglist); 
} 

Tuttavia questo codice non funziona come previsto errorsLogger contiene un po 'strano corde - sembra argomenti variabili non è stata approvata. Come risolvere il mio codice per essere valido?

+1

è necessaria una versione di 'Error' che prende un [' va_list'] (http://en.cppreference.com/w/cpp/utility/variadic/va_list). – BoBTFish

+1

Considerare la modifica dell'interfaccia del logger in modo che assomigli a 'ostream', sarete in grado di fare cose come:' Logger :: error() << "la variabile x è" << x; 'In effetti' Logger :: error() 'può restituire un' ostream & ' – piokuc

+0

posso semplicemente formattare una stringa come primo passo e poi inoltrare semplicemente std :: string? – javapowered

risposta

13

La formulazione tipica di questo in C è di avere due funzioni, quella che accetta ... e uno che accetta un va_list (ad esempio, printf contro vprintf). In C++ è conveniente farlo con sovraccarichi:

// public 
void Logger::Error(const std::string& format, ...) { 
    va_list args; 
    va_start(args, format); 
    Error(format, args); 
    va_end(args); 
} 

// private 
void Logger::Error(const std::string& format, va_list args) { 
    if (this != &errorsLogger) 
     errorsLogger.Error(format, args); 

    vfprintf(logFile, format.c_str(), args); 
    fprintf(logFile, "\n"); 
    fflush(logFile); 
} 

con C++ 11, è possibile fare direttamente con un modello variadic. È inoltre possibile inoltrare argomenti alle funzioni variadiche in stile C.

template<class... Args> 
void Logger::Error(const std::string& format, Args&&... args) {  
    if (this != &errorsLogger) 
     errorsLogger.Error(format, std::forward<Args>(args)...); 

    fprintf(logFile, format.c_str(), std::forward<Args>(args)...); 
    fprintf(logFile, "\n"); 
    fflush(logFile); 
} 
+0

È possibile utilizzare i modelli variadici per inoltrare le funzioni Cdddiche. [Esempio dal vivo] (http://melpon.org/wandbox/permlink/0fbi8R2PCrOJkeFv) –

4

In breve, non è possibile.

Tutto quello che puoi fare è scrivere una funzione membro equivalente che prende uno va_list invece di argomenti variabili e passa lo va_list inizializzato in basso.

+0

Perché stai facendo downvoting? –

+1

Forse qualcuno voleva che fosse più breve? Oppure sono un chimico organico che preferisce scrivere OC (OH) ₂? Difficile dirlo, davvero. –

+0

@CodyGray LOL, punto di riferimento per i chimici organici. –

0

Per funzionare, Logger::Error avrebbe dovuto essere dichiarato ad accettare un va_list come parametro, molto simile vfprintf, piuttosto che argomenti variabili in forma di ... come fprintf.

Problemi correlati