2016-05-03 10 views
-2

Ich versuche, ein Makro zu erstellen, die eine Variadic-Funktion aufrufen, die eine Vorlage verwendet. Ich verwende den folgenden Code, aber der Linker einen Aufruf an das Makro nicht lösen kann ...Variadic Funktionen in Makro und Vorlagen

Dieser Code Teil der Logger-Klasse ist:

template< typename ... Args > 
void Logger::logTrace(Args const& ... args) 
{ 
    std::ostringstream stream; 
    using List = int[]; 
    (void)List{ 0, ((void)(stream << args), 0) ... }; 
    BOOST_LOG_SEV(log_, trace) << stream.str(); 
} 

Die Logger Klasse:

class Logger { 

public: 
    static Logger* getInstance(const char *logFile = "LogClient.log"); 

    template< typename ... Args > 
    void logTrace(Args const& ... args); 

private: 
    Logger(std::string fileName); 
    virtual ~Logger(); 

    void initialize(std::string fileName); 

    static Logger* logger_; // singleton instance 
}; 

und das Makro:

#define LOG_TRACE(...) Logger::getInstance()->logTrace(__VA_ARGS__); 

Ein Aufruf an das Makro:

LOG_TRACE("A log with a number: %d", 5); 

Vielen Dank für Ihre Hilfe!

EDIT UND LÖSEN:

Das Problem ist nicht auf variadische Funktion oder sogar Makro verwandt war, aber mit zu verbinden. Implementieren Sie logTrace in der Klassendefinition, um das Problem zu beheben.

Code Arbeits:

`Der Logger Klasse:

class Logger { 

public: 
    static Logger* getInstance(const char *logFile = "LogClient.log"); 

    template< typename ... Args > 
    void logTrace(Args const& ... args) 
    { 
     std::ostringstream stream; 
     using List = int[]; 
     (void)List{ 0, ((void)(stream << args), 0) ... }; 
     BOOST_LOG_SEV(log_, trace) << stream.str(); 
    } 

private: 
    Logger(std::string fileName); 
    virtual ~Logger(); 

    void initialize(std::string fileName); 

    static Logger* logger_; // singleton instance 
}; 

und das Makro:

#define LOG_TRACE(...) Logger::getInstance()->logTrace(__VA_ARGS__); 

Ein Aufruf an das Makro:

LOG_TRACE("A log with a number: %d", 5); 
+0

Mögen Sie zeigen die 'Logger' Klassendefinition? – shrike

+0

Ich habe den Beitrag aktualisiert – Kryx

+0

Warum möchten Sie ein Makro anstelle einer Funktion verwenden? – Holt

Antwort

1

Sie haben rief dein Makro (und also die logTrace-Template-Funktion) in einer Quelldatei, in der,deklariert, aber nicht definiert/implementiert ist (z. B. in einer Quelldatei, in die Sie Logger.h eingefügt haben). Die vollständige Definition der LogTrace-Vorlagenfunktion ist erforderlich, damit Ihr Makro funktioniert.

Ich schlage vor, Sie LogTrace Member-Funktion in die Logger-Klasse definieren:

class Logger { 

public: 
    static Logger* getInstance(const char *logFile = "LogClient.log"); 

    template< typename ... Args > 
    void logTrace(Args const& ... args) 
    { /* add implementation here */ } 
    ... 
+0

Schön, es funktioniert gut! Ich bearbeite den Beitrag mit der Lösung, vielen Dank – Kryx