宏定義的巧用

1. #用來標記參數是字符串

#define STRING(X) #X
const char *str = STRING(test);
cout << str << endl;

這裏str的內容就是"test"

2. ##用來連接參數

#define AND(X) X##X
int num = AND(8);
cout << num << endl;

這裏num的內容就是88

3. __VA_ARGS__可變參數宏

#define PRINTF_ERROR(format, ...) \
        printf("[%s %s] [ERROR] %s:%d %s() " format" errno:%d err:%s\n", \
        __DATE__, __TIME__, __FILE__, __LINE__,	__FUNCTION__, \
        ##__VA_ARGS__, errno, strerror(errno))
PRINTF_ERROR("test::print %s %s", str1, str2);

format照寫,__VA_ARGS__是系統預定義宏,代表了...這個可變參數列表。

其實在gcc中還支持可變參數名

#define PRINTF_ERROR(format, args...) \
        printf("[%s %s] [ERROR] %s:%d %s() " format" errno:%d err:%s\n", \
        __DATE__, __TIME__, __FILE__, __LINE__,	__FUNCTION__, \
        ##args, errno, strerror(errno))
PRINTF_ERROR("test::print %s %s", str1, str2);

這樣可以用args代替可變參數列表...

這裏__VA_ARGS__和args前面都帶上了##,是因爲如果你使用PRINTF_ERROR,卻沒有可變參數,例如

PRINTF_ERROR("server start success");

就會編譯報錯。爲了兼容有可變參數和沒有可變參數的情況,加上了##

細心的會發現format和前面的引號之間有空格,這是因爲C++11告警invalid suffix on literal; C++11 requires a space between literal and identifier [-Wliteral-suffix]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章