提问人:Leon 提问时间:9/27/2019 最后编辑:Leon 更新时间:9/28/2019 访问量:104
如何绕过 << 调用,就好像 c++ 中的“#ifndef DEBUG”宏一样?
How to bypass a << calling as if "#ifndef DEBUG" macro in c++?
问:
我为自己编写了一个小 logging-lib,它接受两种形式的调用。
一个喜欢普通的函数调用,另一个喜欢 std::ostream <<运算符输出。 然后,我分别为每个日志级别定义了一些宏,如下所示:
#ifdef DEBUG
#define LOG_DEBUG( strLogBody ) appendLog( leon_log::LogLevel_e::ellDebug, std::string( __func__ ) + "()," + ( strLogBody ) )
#define LOG_INFOR( strLogBody ) appendLog( leon_log::LogLevel_e::ellInfor, std::string( __func__ ) + "()," + ( strLogBody ) )
#define log_debug ( Logger_t( LogLevel_e::ellDebug ) << __func__ << "()," )
#define log_infor ( Logger_t( LogLevel_e::ellInfor ) << __func__ << "()," )
//...more for other log-levels
#else
#define LOG_DEBUG( strLogBody )
#define LOG_INFOR( strLogBody ) appendLog( leon_log::LogLevel_e::ellInfor, ( strLogBody ) )
#define log_debug ( Logger_t( LogLevel_e::ellDebug ) )
#define log_infor ( Logger_t( LogLevel_e::ellInfor ) )
//...more for other log-levels
#endif
当客户端代码空间中定义了“DEBUG”宏时,两者都形成用于调试目的的产品目标代码。 当没有定义“DEBUG”宏时,前一种形式(喜欢函数调用)不会产生任何二进制代码来加速我的应用程序(如我所愿),而后一种形式仍然提供代码。
有没有办法,我可以绕过那些“<<”调用,就像处理那些正常的函数调用一样?
到目前为止,我正在使用与@Botje给出的解决方案类似的解决方案。区别在于 mines 是 Logger_t 的 friend-func,而 Botje's 是成员 func。 以下是我的:
template <typename T>
inline Logger_t& operator<<( Logger_t& lgr, const T& body ) {
if ( lgr.m_LogLevel >= g_ellLogLevel )
dynamic_cast<std::ostringstream&>( lgr ) << body;
return lgr;
};
但我猜 GCC 仍然生产调用二进制代码的函数,即使这些都是“无操作”调用。我不知道如何拆卸我的目标程序,所以我无法确认。
谢谢!请原谅我丑陋的英语!
答:
2赞
Botje
9/27/2019
#1
为什么不在非调试版本中进行无操作:operator<<
#ifndef DEBUG
struct Logger_t {
template <class T>
Logger_t& operator <<(const T& o) { return *this; }
};
#endif
编译器应该能够将整个链简化为零。log_debug << ... << ...
如果还想避免<<链中的函数调用,请定义 for 和operator bool
Logger_t
#define log_debug false && Logger_t{}
评论
0赞
Leon
9/28/2019
多亏了@Botje,我会尝试你的第二种方法。
0赞
Leon
9/28/2019
我用你的方法得到了我想要的2!谢谢!
评论