可以使用#define printf
刪除對printf()
的所有調用。如果我有很多調試打印,如std::cout << x << endl;
怎麼辦?如何使用預處理器快速關閉cout <<
語句在單個文件中?使用預處理器取消std :: cout代碼行
IFDBG(cout << result << endl);
然後你就可以定義宏相應:
可以使用#define printf
刪除對printf()
的所有調用。如果我有很多調試打印,如std::cout << x << endl;
怎麼辦?如何使用預處理器快速關閉cout <<
語句在單個文件中?使用預處理器取消std :: cout代碼行
IFDBG(cout << result << endl);
然後你就可以定義宏相應:
如果您正在尋找快速刪除調試語句的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;
}
小心這最後一個,因爲這也將接受定期的功能指針。
替換你有這樣的調試輸出語句
#ifdef DEBUG
# define IFDBG(x) x
#else
# define IFDBG(x)
#endif
這看起來不像它可以與IFDBG(cout << foo(x,y)<< std :: endl);'一起使用。逗號將打破宏觀。 – MSalters 2009-09-07 14:10:41
不,這不會破壞宏,因爲宏可以在括號內轉義範圍。然而這個調用會打破它:IFDBG(cout << foo
你或許可以做一個預處理器黑客工具,定義了一個新的流狀類,一個名爲cerr
的實例,它什麼都不做。如果你真的很幸運,編譯器會看到這個函數什麼也不做,並優化operator<<()
的調用。
喜歡的東西
class NullStream
{
public:
NullStream();
NullStream& operator<<(const std::string& text) { return *this; }
// And operators for other types, too
}
static NullStream cerr;
這是相當黑客但是,它的(遠)更好地通過你的來源並添加記錄適當的支持。
作爲一種通用的原則,應該避免記錄到標準輸出 - 要更好地記錄到日誌文件,然後可以使用標準配置工具來更改日誌級別或完全關閉它。
只是我的$ 0.02 .....
爲「開卷」已經說了,快速的解決方案是一個什麼都不做流。還有更好的實現,但:
class NullStream {
public:
NullStream() { }
template<typename T> NullStream& operator<<(T const&) { return *this; }
};
你仍然有輕微的問題與std::cout
因爲這三個令牌序列,你真的不想重新定義std
或cout
獨立。一個簡單的解決方案是
#ifdef NDEBUG
#define COUT std::cout
#else
#define COUT NullStream()
#endif
COUT << "Hello, world" << std::endl;
定義一個代替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
一樣。
定義該宏:
#ifdef DEBUG
#define MY_LOG std::cout
#else
#define MY_LOG if(false) std::cout
#endif
這個宏的優勢是在編譯器優化
如果放在那些國際單項體育聯合會內的表達式是常數,在編譯的時間確定的,那麼你可能會幾乎可以肯定,編譯器已經將它們從代碼中刪除了... https://stackoverflow.com/a/14657645/5052296
如果我將endl傳遞給這個流,它會給出錯誤..看起來像T&item不接受endl ..任何線索如何超載它呢? – 2011-12-13 11:01:01
針對操縱器更新的答案。 – 2011-12-13 20:16:50
非常感謝,我明白這一點 – 2011-12-14 09:56:31