2014-02-05 70 views
1

我有如下簡單的日誌記錄類。連接兩個C++語句

#include <iostream> 
#include <string> 

using namespace std; 

class log 
{ 
public: 
    log(){}; 
    ~log(){}; 
    log & operator << (int x){ cout << x; return * this;} 
    log & operator << (string x){ cout << x; return * this;} 
    log & operator << (log & (log::*pf)()){ (this->*pf)(); return * this;} 
    log & end() { cout << "\r\n"; return * this;} 
}; 

log l; 

#define end    &log::end; 
#define error(z)  l << "ERROR " z << end; 
#define warn(z)  l << "WARN " z << end; 

int main() 
{ 
    int y = 20; 

    error (<< y); 
} 

有沒有什麼辦法可以像我這樣寫我的代碼?

error << y; 
這裏

基本思路,是爲了避免用戶使用宏年底

即我不希望用戶編寫類似下面

error << y << end; 
+7

做你想做的事嗎?按照預期使用'<<'運算符。或者只提供輸出所需前綴的'error()'和'warn()'函數。這裏不需要宏! – TypeIA

+0

您可能想看看[boost.log](http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/index.html)。 –

+0

爲什麼不從ostream派生類日誌並重載運算符<<,以便在給定的上下文中表現如此? – jpmuc

回答

0

什麼:

#define LOG(Msg) do { l << Msg << ::std::endl; } while(0) 

Log("Hello" << "World"); 

注意:我用am在調試版本中,像這樣使用它((void)0)在發佈版本中。

對於常見的日誌記錄,你不應該使用宏,並可能考慮流操縱器。

1

看起來你正在重新發明方車輪給我!的確,有很多記錄器庫(boost.log是一個很好的)。另一種解決方案是讓用戶編寫標準語法包括調用std::endl

error << x << std::endl; 
warn << y << std::endl; 

你可以通過傳遞一個字符串"warn""error"log類的construtor。 您必須截取Overload handling of std::endl?中所述的std::endl參數。

0

一個辦法是刪除你的全局變量和使用您的析構函數具有宏寫換行符創建一個範圍,所以,對象被銷燬:

#define error(z)  {log l; l << "ERROR " z; } 
#define warn(z)  {log l; l << "WARN " z; } 

這將產生代碼接近出現什麼你要沒有你端的微距:

int y = 20, z = 40; 
error (<< y << " " << z); 

如果你喜歡這樣的方式,你可能要考慮改善宏觀所以日誌級別宏本身執行,讓對象不與也沒什麼每個日誌消息創建如果在t的表現帽子等級對你很重要。

在這裏沒有看到POCO日誌記錄的插件,這就是我使用的。不是說這對你有用,這正是我喜歡我的特殊需求。

0

您可以創建類:

class PrefixLog 
{ 
public: 
    explicit PrefixLog(const char* prefix) : prefix(prefix) {} 
    template <typename T> 
    log& operator << (const T& t) const { return l << prefix << t << &log::end; } 
private: 
    const char* prefix; 
}; 

PrefixLog error("ERROR "); 
PrefixLog warning("WARN "); 

然後

warning << y; 
error << y; 
爲什麼地球上