2012-10-26 28 views
0

我有這樣一個日誌生成器類型,以便:C++ Builder的方式插入操作``<<風格

Log Log::log(const int logLevel) 
{ 
    return Log(logLevel); 
} 

Log& operator <<(Log& log, const char * s) 
{ 
    if (log.hasLogLevel()) 
     log.out << s; 
    return log; 
} 

我用上面的代碼是這樣的:

Log::log(1) << "Hello logger"; 

但我得到這些警告,直到最近我才意識到,這是因爲運營商超負荷的方式(或至少這是我在想什麼)

warning C4239: nonstandard extension used : 'argument' : conversion from 'snow::Log' to 'snow::Log &' 

我以爲這會很好,因爲它是一樣的rvalue通過這些運算符重載傳遞/鏈接。我不認爲這段代碼是在MSVC++之外編譯的,我想知道我應該在這裏做些什麼改變。

如果解決方案是簡單地使用右值引用,那麼我很酷,但我想更好地理解這裏發生了什麼。

回答

4

問題 Log是一個右值,並且不允許綁定到非const引用參數。微軟並沒有強制執行這一點,他們有一些遺留的代碼會破壞。

如果您只想輸出字符串,則一種解決方法是使operator<<成爲Log類的成員。你允許調用右值的成員。

如果您想使用其他非成員運算符,則可以爲左值轉換器提供一個右值,就像標準流在C++ 11中所做的那樣。

喜歡的東西

template<class T> 
Log& operator<<(Log&& log, const T& value) 
{ return log << value; } 

使用的事實,內部操作log是一個左值,並且可以結合到其它運營商的一個非const引用。

+0

好的,但是如果我將操作符重載的類型更改爲'Log&operator <<(Log && log,const char * s)'那很好,對不對?這可能更符合我想在這裏做的事情。 –

+1

@JohnLeidegren使運營商成爲會員有什麼問題? –

+0

沒什麼,我很好......只是問...試着更好地理解。 –