C言語リロードマクロ関数のテクニック

2768 ワード

C/C++言語を書くときによく使われるマクロ定義ですが、マクロ関数はパラメータ付きマクロ定義です(blablabla......背景紹介は省略).
いくつかのパラメータバージョンのマクロ定義が必要になる場合があります.たとえば、次のようにします.
1
2
#define MACRO_FUN(a) doSomethingWithOneArg(a)
#define MACRO_FUN(a, b) doSomethingWithTwoArgs(a, b)
しかし、マクロ定義は正規関数のように再ロードされず、定義されたマクロを繰り返し定義しようとすると、前の定義が上書きされます.では、マクロ関数を正しく再ロードするにはどうすればいいのでしょうか.
まず、可変パラメータマクロ__について理解する必要があります.VA_ARGS__,__VA_ARGS__マクロのパラメータ...を展開できます.たとえば、次のようにします.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define F(...) f(__VA_ARGS__)
#include
 
int
f
(
int
a
,
int
b
,
int
c
)
{
return
a
+
b
+
c
;
}
 
int
main
(
void
)
{
printf
(
"%d"
,
F
(
1
,
2
,
3
)
)
;
//outputs 6
 
return
0
;
}
奇跡を目撃する時が来ました.1つまたは2つのパラメータを再ロードできるマクロ関数を例に挙げます.
1
2
3
4
5
6
7
8
9
#define OneArgument(a)//...action with one argument
#define TwoArguments(a, b)//...action with two arguments
 
#define GetMacro(_1, _2, NAME, ...) NAME
#define Macro(...) GetMacro(__VA_ARGS__, TwoArguments, OneArgument, ...)(__VA_ARGS__)
 
//usage:
Macro
(
a
)
;
//OneArument(a) is called
Macro
(
a
,
b
)
;
  
//TwoArguments(a, b) is called
tada!反応していないのではないでしょうか.これは何の役に立ちますか.このマクロ定義がどのように動作するかをテストし、まずパラメータの状況を見てみましょう.Macro(a) => GetMacro(a, TwoArguments, OneArgument) => OneArgument(a)
2つのパラメータの場合:Macro(a, b) => GetMacro(a, b, TwoArguments, OneArgument) => TwoArgument(a, b)
マクロ関数のリロード機能が巧みに実現されていますが、3つのパラメータのリロードはどのように実現されますか.
1
2
3
4
5
6
7
8
9
10
11
#define OneArgument(a)//...action with one argument
#define TwoArguments(a, b)//...action with two arguments
#define ThreeArguments(a, b, c)//...action with three arguments
 
#define GetMacro(_1, _2, _3, NAME, ...) NAME
#define Macro(...) GetMacro(__VA_ARGS__, ThreeArguments, TwoArguments, OneArgument, ...)(__VA_ARGS__)
 
//usage:
Macro
(
a
)
;
//OneArument(a) is called
Macro
(
a
,
b
)
;
  
//TwoArguments(a, b) is called
Macro
(
a
,
b
,
c
)
;
  
//ThreeArguments(a, b, c) is called
ブログのソースアドレス:http://blog.nemoge.com/trick-for-overload-macro-function-in-c/