2013-09-01 18 views
0

我正在創建一個小型的日誌記錄類,它允許使用模板函數實現可變長度參數列表的printf-like語法(禮貌boost :: format)。我認爲我很接近:在實例化Log對象「記錄器」之後,我想能夠編寫logger.Print("This %s is a %s", some_obj, another_obj);。我目前擁有它的方式會在「日誌」中產生錯誤「No member named'Print'」。將模板函數與類混合使用

任何人都可以提出我需要改變?

Log.h:

#ifndef LOG_H 
#define LOG_H 
#include <string> 
using std::string; 

#include <sstream> 
#include <ostream> 
#include <fstream> 
#include <boost/format.hpp> 

enum Severity { 
    DEBUG, 
    INFO, 
    WARN, 
    CRIT, 
    DIE, 
    LEVELS  // always last; holds # of severity levels 
}; 


class Log { 

public: 
    Log(); 
    Log(const char*, const char*); 

    void Print_r(int, const boost::format&); 

private: 
    static const char * sev_code[]; 

    // order is important here! 
    std::ofstream output_file_stream; // this must be initialized .. 
    std::ostream& output_stream;  // .. before this is bound. 
}; 

int LEVEL; // (where does this belong?) 

// This unpacks the variadic arguments one at a time recursively 
template <typename T, typename... Params> 
    void Print_r (int severity, boost::format &boost_format, const T &arg, const Params&... parameters) { 
    Print_r(severity, boost_format % arg, parameters...); // recursively unpack 
} 

// This checks severity and converts pat to boost::format 
template <typename... Params> 
void Print (int severity, const string &pat, const Params&... parameters) { 
    if (severity < LEVEL) return; 
    boost::format boost_format(pat); 
    Print_r(severity, boost_format, parameters...); 
} 

#endif 

Log.cpp:

#include "Log.h" 
#include <iostream> 
using std::cout; 
using std::endl; 

#include <string> 
using std::string; 

#include <fstream> 

const char * Log::sev_code[] = { 
    "DBUG", 
    "INFO", 
    "WARN", 
    "CRIT", 
    "DIE " 
}; 

// Constructor w/no parms = logging to cout 
Log::Log() : 
    output_stream(cout) { 

} 

// Constructor w/parms = logging to file 
Log::Log(const char* dir, const char* file) : 
    output_stream(output_file_stream) { 

    string output_file_name = string(dir) + "/" + string(file); 
    output_file_stream.open(output_file_name.c_str(), std::ofstream::out); 
} 

// This does the actual logging of the formatted message to the 
// output_stream: 
void 
Log::Print_r (int severity, const boost::format &boost_format) { 
    std::stringstream s; 
    s << "[" << sev_code[severity] << "] " 
     << boost_format; 
    output_stream << s << endl; 
} 
+1

http://stackoverflow.com/q/495021/279982 – atoMerz

回答

0

從這個代碼打印模板Log類之外。你需要在類定義中移動它。

+0

是的,這是問題所在。我對模板函數和成員函數之間的關係有些困惑。顯然這些是正交的。 – Chap