C言語のマクロのオーバーロード
同じ名前のマクロに対して、渡す引数の数に応じて異なる処理(マクロ)を呼び出す(展開する)。
C/C++ のマクロでは、可変長引数マクロ(VA_ARGS)とマクロの連結(##)を組み合わせることで、擬似的にオーバーロードを実現する。
なお、古いMSVCでは、コンパイラがマクロを正しく展開できない(VA_ARGS を一つの引数として誤認識する)。そのため、一つマクロ展開をはさむことで、VC++ のプリプロセッサがマクロを正確に再帰評価し、意図した通りのマクロのオーバーロードとして動作が可能となる。
マクロのオーバーロード(単純版)
引数の数に応じて展開するマクロを選択する。SELECTER の定義および呼び出す際のマクロの列挙は、必要に応じて変更する。
// 呼び出されるマクロ
#define MACRO_1(a) ptintf("1")
#define MACRO_2(a, b) ptintf("2")
#define MACRO_3(a, b, c) ptintf("3")
#define MACRO_4(a, b, c, d) ptintf("4")
#define MACRO_5(a, b, c, d, e) ptintf("5")
// マクロのオーバーロード(単純版)
#define EXPAND(x) x
#define SELECTER(m1, m2, m3, m4, m5, NAME, ...) NAME
#define MY_MACRO(...) EXPAND(SELECTER(__VA_ARGS__, MACRO_5, MACRO_4, MACRO_3, MACRO_2, MACRO_1)(__VA_ARGS__))
void main() {
MY_MACRO(10); // MACRO_1 が呼ばれる
MY_MACRO(10, 20); // MACRO_2 が呼ばれる
}
マクロのオーバーロード(一般化版)
呼び出すマクロが MACRO_1、MACRO_2 ... のように マクロ名+引数の数 と一般化して、引数の数で呼び出すマクロを選択する。
// 呼び出されるマクロ
#define MACRO_1(a) ptintf("1")
#define MACRO_2(a, b) ptintf("2")
#define MACRO_3(a, b, c) ptintf("3")
#define MACRO_4(a, b, c, d) ptintf("4")
#define MACRO_5(a, b, c, d, e) ptintf("5")
// マクロのオーバーロード
#define EXPAND(x) x
#define _VA_COUNT(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, COUNRTER, ... ) COUNRTER
#define _VA_NUMBER(...) EXPAND(_VA_COUNT( __VA_ARGS__ , 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ))
#define _VA_CONCAT(a, b) a##b
#define _VA_SELECTER(macro, count) _VA_CONCAT(macro, count)
#define MY_MACRO(...) EXPAND(_VA_SELECTER(MACRO_,_VA_NUMBER(__VA_ARGS__))(__VA_ARGS__))
void main() {
MY_MACRO(10); // MACRO_1 が呼ばれる
MY_MACRO(10, 20); // MACRO_2 が呼ばれる
}
最終更新時間:2026年07月10日 09時16分59秒 指摘や意見などあればSandBoxのBBSへ。