C++ 在变量宏中获取多个变量列表的选项有哪些?
我一直在尝试使用可变宏来减少我正在使用的一些SFINAE模式中的冗余代码。具体来说,我想使用可变宏生成函数定义。(这个问题与SFINAE无关)。对于我的应用程序,我想编写一个调用现有成员函数的包装函数。实际的应用程序需要我生成一个带有SFINAE专门化的模板结构,因此有一些重复性的东西,只要有一个宏负责生成结构和函数就好了。这就是动机 下面的示例省去了所有SFINAE内容,只定义了一个包含三个具有不同参数列表的静态函数(f0、f1、f2)的结构,并尝试通过全局宏生成的函数调用这些函数。你为什么要这么做??你不会的。但这只是为了说明我在SFINAE应用程序中遇到的问题C++ 在变量宏中获取多个变量列表的选项有哪些?,c++,c,macros,variadic-macros,C++,C,Macros,Variadic Macros,我一直在尝试使用可变宏来减少我正在使用的一些SFINAE模式中的冗余代码。具体来说,我想使用可变宏生成函数定义。(这个问题与SFINAE无关)。对于我的应用程序,我想编写一个调用现有成员函数的包装函数。实际的应用程序需要我生成一个带有SFINAE专门化的模板结构,因此有一些重复性的东西,只要有一个宏负责生成结构和函数就好了。这就是动机 下面的示例省去了所有SFINAE内容,只定义了一个包含三个具有不同参数列表的静态函数(f0、f1、f2)的结构,并尝试通过全局宏生成的函数调用这些函数。你为什么要
#include<iostream>
struct Foo
{
static void f0()
{
std::cout<<"f0() called"<<std::endl;
}
static void f1(int a)
{
std::cout<<"f1("<<a<<") called"<<std::endl;
}
static double f2(int a, double b)
{
std::cout<<"f2("<<a<<","<<b<<") called"<<std::endl;
return a*b;
}
};
#define VA_LIST(...) __VA_ARGS__
#define FUNCTION_WRAPPER(NAME,RTYPE,PARAMS,ARGS)\
RTYPE NAME(PARAMS)\
{\
return Foo::NAME(ARGS);\
}
FUNCTION_WRAPPER(f0,void,VA_LIST(),VA_LIST())
FUNCTION_WRAPPER(f1,void,VA_LIST(int a),VA_LIST(a))
FUNCTION_WRAPPER(f2,double,VA_LIST(int a, double b), VA_LIST(a, b))
int main()
{
f0();
f1(1);
f2(1,4.2);
return 0;
}
将变量列表用作参数3和3。请注意,参数列表和参数列表必须彼此一致(即参数列表中传递的变量最好在参数列表中声明)
这似乎适用于本例,但如果我们试图在调用的开头添加一个固定参数(例如Foo::NAME(fixedArg,ARGS)),则会出现一些问题。如果变量列表为空,####uu VA_ARGS吞下逗号的技巧似乎不适用于这种方法
所以我的问题是:
#define VA_LIST2(...) __VA_ARGS__
#define FUNCTION_WRAPPER2(NAME,RTYPE,PARAMS,ARGS)\
RTYPE NAME##_2(PARAMS)\
{\
return Foo::NAME(1,ARGS);\
}
FUNCTION_WRAPPER2(f2,double,VA_LIST2(double b), VA_LIST2(b))
将##插入函数_包装器体的错误为
error: pasting "," and "VA_LIST" does not give a valid preprocessing token
return Foo::NAME(1,##ARGS);\
将##插入VA#列表宏体的编译错误为:
error: '##' cannot appear at either end of a macro expansion
#define VA_LIST2(...) ##__VA_ARGS__
^
我相信使用GCC
###
删除逗号的语法如下:#定义宏(X,…)扩展(X,###VA#u ARGS#)
。它必须跟在逗号、前缀\uuuu VA\u ARGS\uuuu>或命名的等效项之后,而不是独立宏的一部分。请参阅。此外,根据预处理器查看它的方式,我猜函数包装器在VA\u LIST`之前展开过,因此从它的角度来看,实际上可以看到零变量参数列表。不确定是否这是一种有效的方法(因此没有给出答案),但是,它应该完全在任何现代C/C++编译器的处理能力范围内。建议阅读/#包括:我相信使用GCC#
删除逗号的语法如下:#定义宏(X,…)扩展(X,####VA#
。它必须跟在逗号、前缀\uuuu VA\u ARGS\uuuu>或命名的等效项之后,而不是独立宏的一部分。请参阅。此外,根据预处理器查看它的方式,我猜函数包装器在VA\u LIST`之前展开过,因此从它的角度来看,实际上可以看到零变量参数列表。不确定是否这是一种有效的方法(因此不会给出答案),但是,它应该完全在现代C/C++编译器的处理能力范围内。建议阅读/#包括:
error: '##' cannot appear at either end of a macro expansion
#define VA_LIST2(...) ##__VA_ARGS__
^