C + + 宏没有从 C 改变。因为 C 没有函数的重载参数和默认参数,所以当然也没有宏的参数。所以回答你的问题: 不,这些特性不存在于宏中。您唯一的选择是使用不同的名称定义多个宏(或者根本不使用宏)。
As a sidenote: In C++ it's generally considered good practice to move away from macros as much as possible. If you need features like this, there's a good chance you're overusing macros.
#include <stdio.h>
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#define PP_CONCAT(a,b) PP_CONCAT_(a,b)
#define PP_CONCAT_(a,b) a ## b
#define THINK(...) PP_CONCAT(THINK_, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
#define THINK_0() THINK_1("sector zz9 plural z alpha")
#define THINK_1(location) THINK_2(location, 42)
#define THINK_2(location,answer) THINK_3(location, answer, "deep thought")
#define THINK_3(location,answer,computer) \
printf ("The answer is %d. This was calculated by %s, and a computer to figure out what this"
" actually means will be build in %s\n", (answer), (computer), (location))
int
main (int argc, char *argv[])
{
THINK (); /* On compilers other than GCC you have to call with least one non-default argument */
}
// The multiple macros that you would need anyway [as per: Crazy Eddie]
#define XXX_0() <code for no arguments>
#define XXX_1(A) <code for one argument>
#define XXX_2(A,B) <code for two arguments>
#define XXX_3(A,B,C) <code for three arguments>
#define XXX_4(A,B,C,D) <code for four arguments>
// The interim macro that simply strips the excess and ends up with the required macro
#define XXX_X(x,A,B,C,D,FUNC, ...) FUNC
// The macro that the programmer uses
#define XXX(...) XXX_X(,##__VA_ARGS__,\
XXX_4(__VA_ARGS__),\
XXX_3(__VA_ARGS__),\
XXX_2(__VA_ARGS__),\
XXX_1(__VA_ARGS__),\
XXX_0(__VA_ARGS__)\
)
上面的例子(来自 Derek Ledbetter、 David Sorkovsky 和 Joe D)没有一个用宏来计算参数,我使用的是 Microsoft VCC 10。__VA_ARGS__参数总是被认为是一个单独的参数(使用 ##或不使用 ##进行标记化) ,因此这些示例所依赖的参数转换不起作用。
Uses only 标准 C99 macros to achieve function overloading, no GCC/CLANG/MSVC extension involved (i.e., comma swallowing by the specific expression , ##__VA_ARGS__ for GCC/CLANG, and implicit swallowing by ##__VA_ARGS__ for MSVC). So feel free to pass the missing --std=c99 to your compiler if you wish =)
适用于 零参数,以及 无限数量的参数,如果您进一步扩展它以满足您的需要
工作合理 跨平台,至少测试
GNU/Linux + GCC (CentOS 7.0 x86 _ 64上的 GCC 4.9.2)
GNU/Linux + CLANG/LLVM ,(CLANG/LLVM 3.5.0 on CentOS 7.0 x86 _ 64)
OS X + XCode ,(OS X Yosemite 10.10.1上的 XCode 6.1.1)
Windows + Visual Studio (Visual Studio 2013 Update 4 on Windows 7 SP164 bit)
CREATE_1后面的 ,是 GCC/CLANG 的一种解决方案,它在将 -pedantic传递给编译器时抑制了一个(假阳性)错误,即 ISO C99 requires rest arguments to be used。FUNC_RECOMPOSER是 MSVC 的解决方案,或者它不能正确地计算宏调用括号内的参数数量(例如,逗号)。结果进一步决定