C++ Debug 宏与简易qDebug

Methods

  • T(block): 在代码块前后插入提示文字(包含代码块行号), 以确定代码块是否被执行以及是否执行成功.
  • V(variable): 打印变量名及其值.
  • log(): 返回一个错误流, 该错误流自动添加空格和换行符, 并且支持注册自定义类型和格式, 例如显示打印string中的转义字符, 打印vector等.

Example Usage

T(
int root = 0;
dfs(root);
)

int age = 97;
V(age)
    
vector<vector<int> > tree(2);
tree[0] = {0, 1};
log() << "hello vector:" << tree << 1;
log() << "hello
 string:" << string("
_n/") << 2;

TRY  line 4

DONE line 4
age = 97
hello vector: vector(vector(0, 1), vector()) 1
hello
 string: "
_n/" 2

Implementation

#define T(f) cerr << "
TRY  line " << __line__ << endl;
    f;
    cerr << "
DONE line " << __line__ << endl;

#define V(x) cerr << #x << " = " << x << endl;

class log {
public:
    log(): m_space(true) {}
    ~log() { cerr << endl; }
    bool autoInsertSpace() const { return m_space; }
    log& space(bool sp = true) { m_space = sp; return *this; }
    // string
    log& operator<< (const string &s) {
        cerr << """;
        string str = s;
        replace(str, "\", "\\");
        replace(str, "
", "\n");
        replace(str, "
", "\r");
        replace(str, "	", "\t");
        replace(str, "v", "\v");
        replace(str, """, "\"");
        cerr << str << """ << (m_space ? " " : "");
        return *this;
    }
    // vector
    template <typename T>
    log& operator<< (const vector<T> &v) {
        bool initSpace = autoInsertSpace();
        cerr << "vector(";
        for (size_t i = 0; i < v.size(); ++i) {
            if (i) cerr << ", ";
            (*this).space(false) << v[i];
        }
        (*this).space(initSpace) << ")";
        return (*this);
    }
    // default
    template <typename T>
    log& operator<< (const T &x) {
        cerr << x << (m_space ? " " : "");
        return *this;
    }
private:
    void replace(string &str, const string &from, const string &to) {
        for (size_t p = str.find(from); p != string::npos; p = str.find(from, p + to.size())) {
            str.replace(p, from.size(), to);
        }
    }
    bool m_space;
};

以上展示了向log()注册新类型的一种方法, 即添加类函数. 也可以通过在类外重载<<操作符的方式注册. 注意, 无论哪种方法都要确保恢复space状态.

例如:

struct Time {
    int hour, minute, second;
};

log& operator<< (log &lg, const Time &time) {
    bool initSpace = lg.autoInsertSpace();
    lg.space(false) << time.hour << ":" << time.minute << time.second;
    lg.space(initSpace) << "";
    return lg;
}
原文地址:https://www.cnblogs.com/maoruimas/p/13455560.html