Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在MSVC中实现EXCLUDE_FIRST_参数宏?_C++_Gcc_Visual C++ - Fatal编程技术网

C++ 如何在MSVC中实现EXCLUDE_FIRST_参数宏?

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

以下代码在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 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)
宏是用形式参数
定义的;它是用