C++ 如何在MSVC中实现EXCLUDE_FIRST_参数宏?
以下代码在GCC中按预期工作,但在MSVC中不工作C++ 如何在MSVC中实现EXCLUDE_FIRST_参数宏?,c++,gcc,visual-c++,C++,Gcc,Visual C++,以下代码在GCC中按预期工作,但在MSVC中不工作 #define _EXCLUDE_FIRST_ARG_(first, ...) __VA_ARGS__ #define EXCLUDE_FIRST_ARG(...) _EXCLUDE_FIRST_ARG_(__VA_ARGS__) 例如: EXCLUDE_FIRST_ARG(a, b, c, d, e) 将在GCC中评估(也在CLANG中检查) 但是当我在这个例子中使用MSVC时,结果是空的 当我检查\u EXCLUDE\u first\u
#define _EXCLUDE_FIRST_ARG_(first, ...) __VA_ARGS__
#define EXCLUDE_FIRST_ARG(...) _EXCLUDE_FIRST_ARG_(__VA_ARGS__)
例如:
EXCLUDE_FIRST_ARG(a, b, c, d, e)
将在GCC中评估(也在CLANG中检查)
但是当我在这个例子中使用MSVC时,结果是空的
当我检查\u EXCLUDE\u first\u ARG\u
中的first
参数时,我发现参数a、b、c、d、e
都绑定到first
参数,而左..
没有任何内容
这是因为MSVC预处理器缺少一些特性或MSVC违反了一些C++标准吗? 如何使用MSVC?
实现这个ExtReDeFixSTARG功能,这是因为MSVC预处理器缺少参数预存特征还是违反了一些C++标准? 下面是我在微软把它组装起来的最佳方式 1。宏定义:#define _EXCLUDE_FIRST_ARG_(first, ...) __VA_ARGS__
#define EXCLUDE_FIRST_ARG(...) _EXCLUDE_FIRST_ARG_(__VA_ARGS__)
…显然,会导致宏被定义
2。调用
EXCLUDE_FIRST_ARG(a, b, c, d, e)
MS的预处理器识别宏EXCLUDE_FIRST_ARG
之类的函数,因此禁用展开:
2a。参数识别
EXCLUDE_FIRST_ARG(a, b, c, d, e)
宏是用形式参数…
定义的;它是通过参数a、b、c、d、e调用的。这是一个没有命名参数的变量,因此所有参数都绑定到该变量参数
2b。参数替换
EXCLUDE_FIRST_ARG(a, b, c, d, e)
的替换列表中提到了首先排除\u ARG
。它没有被字符串化或参与粘贴。这使得它有资格进行参数替换。在替换参数之前,表达式:
a, b, c, d, e
…由预处理器计算。这些没有什么特别之处(没有类似于函数的宏调用;也没有类似于对象的宏的参数),因此计算是相同的;也就是说,经过计算的参数是:
a, b, c, d, e
根据参数替换规则,替换替换列表中的参数“name”。一旦发生这种情况,我们有:
_EXCLUDE_FIRST_ARG_(a, b, c, d, e)
到目前为止,所有其他主要的预处理器都做同样的事情。但是MS的预处理器在扩展\uu VA\u ARGS\uu
时表现出一种特殊的行为;具体地说,其特点是整个替换仅为一个令牌。您可能会在扩展中看到逗号;我也是;但对于微软来说,这仍然只是一个象征
2[在b和c之间]。串接和粘贴,无特定顺序
这只是此帐户中的语义占位符。这里是这些操作将发生的地方,但由于我们都没有做,所以在这种情况下什么都不会发生
2c。重新扫描和进一步更换
在此步骤中,生成的替换列表本身:
_EXCLUDE_FIRST_ARG_(a, b, c, d, e)
…将重新扫描以获取更多宏。在此重新扫描过程中,预处理器注意到,正在使用“参数”a、b、c、d、e调用宏\u EXCLUDE\u FIRST\u ARG\u
之类的对象(对于其他主要预处理器,这是五个参数)
2c.a。参数识别
EXCLUDE_FIRST_ARG(a, b, c, d, e)
\u EXCLUDE\u FIRST\u ARG\u
有一个命名参数FIRST
,以及一个变量注意:从技术上讲,在C++20之前的预处理器中,必须使用至少2个参数调用此函数;许多主要的预处理器(包括MS)只接受一个
对于MS的预处理器,这是通过一个参数调用的:a、b、c、d、e
,它与参数first
关联。可变参数…
为空
对于大多数其他主要预处理器,这是用五个参数调用的<代码>第一个
与a
关联<代码>带有b、c、d、e的
2c.b。参数替换
EXCLUDE_FIRST_ARG(a, b, c, d, e)
对于MS的预处理器,在替换列表中没有提到first
,因此没有对相关参数进行任何操作<代码>\uuuu VA\u ARGS\uuuuuu
(未进行字符串化/粘贴)不符合MS的逗号省略功能,因此空变量参数会导致将\uuuu VA\u ARGS\uuuuu
替换为placemarker
对于大多数其他主要预处理器,在替换列表中仍然没有提到first
,因此a
没有发生任何变化<代码>(未被字符串化/粘贴)被提及,因此对b,c,d,e
进行评估,结果是b,c,d,e
;该结果将替换\uu VA\u ARGS\uu
2c.c。重新扫描和进一步更换
对于MS的预处理器,这里没有什么有趣的东西。完成后,placemarker将被删除
对于其他预处理器,b、c、d、e
再次被扫描,结果相同
在使用MSVC时,如何实现这个EXCLUDE_FIRST_ARG功能?
在这种情况下,可以使用辅助对象将参数列表与宏分开:
#define _EXCLUDE_FIRST_ARG_(first, ...) __VA_ARGS__
#define CALL(A,B) A B
#define EXCLUDE_FIRST_ARG(...) CALL(_EXCLUDE_FIRST_ARG_,(__VA_ARGS__))
EXCLUDE_FIRST_ARG(a, b, c, d, e)
大致上,EXCLUDE\u FIRST\u ARG
扩展到使用此方法的a.s.阶段中的调用(CALL(EXCLUDE\u FIRST\u ARG-(a、b、c、d、e))
。在重新扫描过程中,调用调用调用,在a.s.期间扩展到\u EXCLUDE\u FIRST\u ARG\u
和(a、b、c、d、e)
,在对每个调用进行完全评估之后。然后在代码>调用< /代码>的RESCAN中,参数列表看起来像多个令牌。这是因为MSVC预处理器缺少参数预存特征还是违反了一些C++标准的MSVC?
下面是我在微软把它组装起来的最佳方式
1。宏定义:
#define _EXCLUDE_FIRST_ARG_(first, ...) __VA_ARGS__
#define EXCLUDE_FIRST_ARG(...) _EXCLUDE_FIRST_ARG_(__VA_ARGS__)
…显然,会导致宏被定义
2。调用
EXCLUDE_FIRST_ARG(a, b, c, d, e)
MS的预处理器识别宏EXCLUDE_FIRST_ARG
之类的函数,因此禁用展开:
2a。参数识别
EXCLUDE_FIRST_ARG(a, b, c, d, e)
宏是用形式参数…
定义的;它是用