2013-10-25 124 views
0

可以將以下代碼縮減爲一個函數嗎?其中大部分是相同的。由於在C++中減少代碼重複

void info(StreamLog &streamLog) 
{ 
    streamLog.ss << "info:"; 
    streamLog.mFilter->setLogLevel("info"); 
} 
void debug(StreamLog &streamLog) 
{ 
    streamLog.ss << "debug:"; 
    streamLog.mFilter->setLogLevel("debug"); 
} 
void warning(StreamLog &streamLog) 
{ 
    streamLog.ss << "warning:"; 
    streamLog.mFilter->setLogLevel("warning"); 
} 
void error(StreamLog &streamLog) 
{ 
    streamLog.ss << "error:"; 
    streamLog.mFilter->setLogLevel("error"); 
} 
void critical(StreamLog &streamLog) 
{ 
    streamLog.ss << "critical:"; 
    streamLog.mFilter->setLogLevel("critical"); 
} 

,如果你需要更多的信息,讓我知道

月1日編輯: 對不起!我沒有清楚地解釋我的情況。我使用這些功能作爲操縱器。因此,我可以做

堵塞< <信息< < ...

堵塞< <警告< < ...

我不想使用

堵塞< <日誌(資訊)< < ...

任何更好的方法?謝謝

回答

10
void log(StreamLog &streamLog, const string& level) 
{ 
    streamLog.ss << level << ":"; 
    streamLog.mFilter->setLogLevel(level); 
} 

總是嘗試看到常見操作並將其抽象爲不同的函數。

2

我和@雷米·班諾特,雖然爲你提供一個選擇,你可以使用一個enum和地圖:

enum log_level { 
    info, debug, warning, error, critical 
} 

void log(StreamLog& streamLog, log_level level) { 
    static const std::map<log_level, std::string> levels = { 
     { info, "info" }, { debug, "debug" }, { warning, "warning" }, 
     { error, "error" }, { critical, "critical" } 
    }; 

    auto iter = levels.find(level); 
    if(iter == levels.end()) return; 

    streamLog.ss << iter->second; 
    streamLog.mFilter->setLogLevel(iter->second); 
} 

這樣做的好處是,你的日誌級別僅限於什麼是在enum(和地圖),但如果你不需要這個約束,最好使用@Rémi的解決方案。

0

這是一個替代Mark的&Rémi的解決方案使用模板。該解決方案在高性能至關重要的領域可能非常有用。這些模板可以讓編譯器將大量信息烘焙到每個模板化函數中,因此應該有一個較小的運行時間成本,尤其是與地圖查找方法相比時。

此外,這將約束在編譯時使用的log_level值,而不是在運行時。

enum class log_level { info, debug, warning, error, critical }; 
template<log_level> struct log_helper{ static const char* const text; }; 

template<> const char* const log_helper<log_level::info>::text = "info"; 
template<> const char* const log_helper<log_level::debug>::text = "debug"; 
template<> const char* const log_helper<log_level::warning>::text = "warning"; 
template<> const char* const log_helper<log_level::error>::text = "error"; 
template<> const char* const log_helper<log_level::critical>::text = "critical"; 

template<log_level level> void set_log_level(StreamLog& streamLog) 
{ 
    streamLog.ss<< log_helper<level>::text << ":"; 
    streamLog.mFilter->setLogLevel(log_helper<level>::text); 
}