C++宏默認是不支持重載的,但可以通過特殊方法讓宏支持重載。
可能你要問,支持宏重載有什麼用處,那麼,就以實例來嘗試宏的重載。
爲了要實現類的動態創建,我還想構建類的繼承關係圖,爲了簡化註冊,所以我需要用宏來簡化註冊。
我需要以下宏來支持:
REG_CREATE1(className)
REG_CREATE2(className, baseName1)
REG_CREATE3(className, baseName1, baseName2)
C++支持多繼承,但爲了方便,我不希望每次註冊的時候,使用不同的宏,那麼我就需要通過一個宏,間接達到重載的效果。
宏本身不支持重載,所以我們不能定義多個重名的宏,但如果我能自動獲取參數個數,那麼可以通過 REG_CREATE ## SIZE 來自動展開成不同參數的宏
第一步、獲取參數個數:
#define PRIVATE_MACRO_VAR_ARGS_IMPL_COUNT(_1,_2,_3,_4,_5,_6,_7,_8,_9, N, ...) N
#define PRIVATE_MACRO_VAR_ARGS_IMPL(args) PRIVATE_MACRO_VAR_ARGS_IMPL_COUNT args
#define COUNT_MACRO_VAR_ARGS(...) PRIVATE_MACRO_VAR_ARGS_IMPL((__VA_ARGS__,10,9,8,7,6,5 4,3,2,1,0))
第二部、實現字符與計算得到的數字進行串接
#define PRIVATE_MACRO_CHOOSE_HELPER2(M, count) M##count
#define PRIVATE_MACRO_CHOOSE_HELPER1(M, count) PRIVATE_MACRO_CHOOSE_HELPER2(M, count)
#define PRIVATE_MACRO_CHOOSE_HELPER(M, count) PRIVATE_MACRO_CHOOSE_HELPER1(M, count)
第三部、實現可以自動轉發的宏
#ifdef WIN32
//EXPAND 用於解決windows上編譯器將__VA_ARGS__展開成一個參數的問題
#define EXPAND(...) __VA_ARGS__
#define REG_DYNCREATE(...) EXPAND(PRIVATE_MACRO_CHOOSE_HELPER(PRIVATE_REG_DYNCREATE_, COUNT_MACRO_VAR_ARGS( __VA_ARGS__))( __VA_ARGS__))
#else
#define REG_DYNCREATE(...) PRIVATE_MACRO_CHOOSE_HELPER(PRIVATE_REG_DYNCREATE_, COUNT_MACRO_VAR_ARGS( __VA_ARGS__))( __VA_ARGS__)
#endif
至此就完成了宏重載效果了