2009-09-07 29 views
4

可以使用#define printf刪除對printf()的所有調用。如果我有很多調試打印,如std::cout << x << endl;怎麼辦?如何使用預處理器快速關閉cout <<語句在單個文件中?使用預處理器取消std :: cout代碼行

IFDBG(cout << result << endl); 

然後你就可以定義宏相應:

回答

3

如果您正在尋找快速刪除調試語句的NullStream可以是一個很好的解決方案。不過,我會建議創建自己的調試類,可以在需要時需要更多的調試功能擴展:

class MyDebug 
{ 
    std::ostream & stream; 
    public: 
    MyDebug(std::ostream & s) : stream(s) {} 
#ifdef NDEBUG 
    template<typename T> 
    MyDebug & operator<<(T& item) 
    { 
     stream << item; 
     return *this; 
    } 
#else 
    template<typename T> 
    MyDebug & operator<<(T&) 
    { 
     return *this; 
    } 
#endif 
}; 

這是一個簡單的設置,可以做你想做最初的東西,再加上它有額外的好處讓你添加功能,例如調試級別等的

更新: 現在,因爲操縱作爲功能實現的,如果你想接受控制器以及(ENDL),您可以添加:

MyDebug & operator<<(std::ostream & (*pf)(std::ostream&)) 
{ 
    stream << pf; 
    return *this; 
} 

而對於所有類型的機械手(這樣你就不必重載所有機械手類型):

template<typename R, typename P> 
MyDebug & operator<<(R & (*pf)(P &)) 
{ 
    stream << pf; 
    return *this; 
} 

小心這最後一個,因爲這也將接受定期的功能指針。

+1

如果我將endl傳遞給這個流,它會給出錯誤..看起來像T&item不接受endl ..任何線索如何超載它呢? – 2011-12-13 11:01:01

+1

針對操縱器更新的答案。 – 2011-12-13 20:16:50

+0

非常感謝,我明白這一點 – 2011-12-14 09:56:31

3

替換你有這樣的調試輸出語句

#ifdef DEBUG 
# define IFDBG(x) x 
#else 
# define IFDBG(x) 
#endif 
+0

這看起來不像它可以與IFDBG(cout << foo(x,y)<< std :: endl);'一起使用。逗號將打破宏觀。 – MSalters 2009-09-07 14:10:41

+1

不,這不會破壞宏,因爲宏可以在括號內轉義範圍。然而這個調用會打破它:IFDBG(cout << foo ()<< std :: endl); – 2009-09-07 14:50:53

3

你或許可以做一個預處理器黑客工具,定義了一個新的流狀類,一個名爲cerr的實例,它什麼都不做。如果你真的很幸運,編譯器會看到這個函數什麼也不做,並優化operator<<()的調用。

喜歡的東西

class NullStream 
{ 
public: 
    NullStream(); 

    NullStream& operator<<(const std::string& text) { return *this; } 
    // And operators for other types, too 
} 
static NullStream cerr; 

這是相當黑客但是,它的(遠)更好地通過你的來源並添加記錄適當的支持。

6

作爲一種通用的原則,應該避免記錄到標準輸出 - 要更好地記錄到日誌文件,然後可以使用標準配置工具來更改日誌級別或完全關閉它。

只是我的$ 0.02 .....

9

爲「開卷」已經說了,快速的解決方案是一個什麼都不做流。還有更好的實現,但:

class NullStream { 
    public: 
    NullStream() { } 
    template<typename T> NullStream& operator<<(T const&) { return *this; } 
}; 

你仍然有輕微的問題與std::cout因爲這三個令牌序列,你真的不想重新定義stdcout獨立。一個簡單的解決方案是

#ifdef NDEBUG 
    #define COUT std::cout 
#else 
    #define COUT NullStream() 
#endif 

COUT << "Hello, world" << std::endl; 
0

定義一個代替cout的宏不是你應該上傳到你的VCS的東西,但是如果你只是在調試過程中臨時執行它,我認爲它可以代替它。所以,你可以只需更換cout通過ostream(0)

#ifdef NDEBUG 
#define cout ostream(0).flush() 
#endif 

這樣一來,它的工作原理既std::cout和滑動cout,並且包括<iostream>ostream可用。寫入ostream(0)是無操作的。 flush函數調用完成後,您可以獲得一個非const引用(所以它也綁定到用於輸出std::string等的非成員operator<<)。因爲它的類型是ostream,它應該像cout一樣。

3

定義該宏:

#ifdef DEBUG 
    #define MY_LOG std::cout 
#else 
    #define MY_LOG if(false) std::cout 
#endif 

這個宏的優勢是在編譯器優化

如果放在那些國際單項體育聯合會內的表達式是常數,在編譯的時間確定的,那麼你可能會幾乎可以肯定,編譯器已經將它們從代碼中刪除了... https://stackoverflow.com/a/14657645/5052296