2015-09-16 66 views
0

當您將變量流式傳輸到輸出流(例如cout)時,類型轉換是自動的。我試圖找出是如何通過函數調用做到這一點,例如:在C++中將流變量作爲函數參數

inline void DEBUG(ostream& s) // Don't know if this prototype is appropriate 
{ 
    cout << s; 
} 


main() 
{ 
    int i = 5; 

    DEBUG("The value is: " << i << endl); // This doesn't compile 

    DEBUG("The value is: " + i + endl); // Neither does this 
} 

我發現這裏類似的問題,但它們都涉及通過流對象作爲參數,而我m試圖將「流式數據」傳遞給一個已經擁有該流對象的函數,所以它是相反的。這甚至有可能嗎?我不想訴諸明確的類型轉換。我也發現this question,但是如果我可以避免的話,我真的不想寫一個完整的記錄器類。

目前我正在實現它作爲一個宏,它的工作原理,但我寧願使用內聯函數,如果可能的話。

#define DEBUG(s) (cout << s) 
+1

這「整個記錄器類」小於二十行的代碼。 – molbdnilo

回答

0

當然,它不編譯。這有很多原因。

首先,運營商< <沒有爲標準流定義,並且您正在嘗試完全做到這一點:在您的DEBUG()中將流串流到流中。 (Pun打算)。

其次,運營商< <沒有爲字符串常量定義的,而你想在這裏調用它:

"The value is: " << i 

+不用於文字定義的兩種,順便說一句。

要實現要查看的語義,您必須從流開始。字符串文字需要首先轉換爲流,並且您可以將< <應用於它。這是實現你想要的唯一方法。

編輯:

現在,因爲我理解的理由,我可以給一個更好的答案。人們試圖用不同的方式分離不同級別的調試有很多方法,並且有幾種庫(log4cpp,boost.log等等)。在開始實施自己的日誌記錄之前,我肯定會建議您查看這些日誌。良好的日誌記錄不僅僅是調試級別。

如果因任何原因,你想用你自己的自制軟件,這裏有幾個recepies的你可能會探索:

  • 使用自己的Logger類(的非常罕見的例子之一,靠近 單一的!在哪裏辛格爾頓是適當的)。你可以不是設置在應用程序的beggining的 日誌記錄級別,並不僅僅是 通話記錄器::調試()< < ...
  • 富民以上宏的解決方案。函數的問題是,與宏不同,它們鬆散的上下文。所以如果你想記錄日誌調用的文件和行號(你通常這麼做!),你可能要做LOG_DEBUG < < ...;這裏LOG_DEBUG會擴展成類似Logger :: debug()< < __FILE__ < <「:」< < __LINE__ < < ....
  • 一旦你做到了這一點,你會看到,有時你撥打< <鏈內的其他功能。在這一點上,你可能會意識到,這些功能將不考慮您的調試級別的調用,並可能會認爲你不想叫他們未啓用調試時(沿行的東西LOG_DEBUG < <「現在目標是」 < <對象。序列化();所以你會希望以豐富的LOG_DEBUG宏不執行任何時調試級別不匹配
  • 而傳奇繼續...準備使用圖書館
+0

的額外間接的唯一原因是有代碼一個地方,我可以啓用/禁用「調試」電平輸出,同時仍然有輸出的其他層面,如「信息」和「警告」。有沒有更好的方法來做到這一點?也許我可以鍵入一個名稱來指向cout,然後將typedef更改爲指向某個空值流? –

+0

不可以。你不能typedef std :: cout。但現在我知道你在做什麼,所以我會更新答案。 – SergeyA

+0

感謝您的提問,這些信息無疑會幫助某人。但既然你建議使用庫或記錄器類+一大堆宏,而我只使用一個宏,我想現在就堅持使用我的1宏。也許在一個更大的項目中我會做不同的事情。再次感謝。 –

0

那麼,什麼(?至少一些)日誌庫會做的是創建一個臨時代理對象,將作爲流:

#include <iostream> 

struct LoggerProxy { 
    LoggerProxy(const char* file, int line) 
    { 
     std::cout << "File " << file << ", line " << line << ": "; 
    } 

    template<typename T> 
    LoggerProxy& operator<<(T&& t) 
    { 
     std::cout << t; 
     return *this; 
    } 
}; 

#define LOG_DEBUG LoggerProxy{__FILE__, __LINE__} 

int main() 
{ 
    LOG_DEBUG << "Value is: " << 4; 
} 

你可以做很多花哨的東西與此,如調試層層把關,輸出到不同的流或多個後端(如同時輸出到std ::法院/ CERR和日誌文件)等等。

相關問題