前述:
ENSURE是windows api 里面的函数,assert的一种扩展,没有开放到标准里面,调用的方式是 ENSURE(exp)(msg)(msg)(msg)…;这种写法很不错,我们可以很直观的写需要打印的东西,虽然跟一般C++的语法看起来不协调。
一般我们习惯使用的记录log的方式是 (“%s : %d”, str, num) printf的组织方式,但是这样经常会遇到的问题是,format部分的代码很容易写错,尤其是 int64 int32这种类型的区分;当然在linux上面其实更习惯用std::cout方式,再做重定向到日志文件中去,避免代码中format的组织。
上面代码是参考网上:
参考了:http://www.cnblogs.com/cbscan/archive/2012/10/26/2740838.html 代码
去掉了try catch的内容,让ENSURELOG的宏定义只是用来打印日志,外层可以写嵌套assert的内容,或者不同种类log的宏。
主要解释了宏的展开式,当时看了好一会儿才绕明白,这里记录一下。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| #include <iostream> #include <sstream>
class CEnsureLog { private: mutable std::string m_osLog; public: CEnsureLog(const char* func, int line, const char* logType, const char* log) { std::ostringstream so; so << "[" << func << ":" << line << "]" << logType << log ; m_osLog = so.str(); } ~CEnsureLog() { if (m_osLog.empty()) return; std::cout << m_osLog.c_str() << std::endl; } template<typename T> CEnsureLog& operator << (const std::pair<const char*, T> p) { std::ostringstream so; so << "[" << p.first << "=" << p.second << "]"; m_osLog += so.str(); return *this; } CEnsureLog& operator << (int) { return *this; } const char* write() const { return m_osLog.c_str(); } }; static int A = 0, B = 0; #define AB(a, N) std::make_pair(#a, a) << N #define A(a) AB(a, B) #define B(a) AB(a, A) #define ENSURELOG(b, logType) if (b); else CEnsureLog(__FUNCTION__, __LINE__, logType, #b) << A
int main() { std::string str = "str"; int num = 11; ENSURELOG(false, "[info]")("abc")(5)(str)(num); return 0; }
|