Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.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++ 为什么可变宏如此令人不快?_C++_C_C Preprocessor_Language Lawyer_Variadic Macros - Fatal编程技术网

C++ 为什么可变宏如此令人不快?

C++ 为什么可变宏如此令人不快?,c++,c,c-preprocessor,language-lawyer,variadic-macros,C++,C,C Preprocessor,Language Lawyer,Variadic Macros,与C++的可变模板相比,CPP(C/C++预处理器;为了简单起见,我将在这个问题中将其视为一种单独的语言)中的可变宏非常有限。本质上,可变宏只是带有参数的宏,其参数允许包含逗号。这并没有提供简单的方法来计算参数、逐个操作参数等。这些都是可能的,但需要复杂、混乱且编译速度慢的黑客,如中所述。使用VA_ARGS可以做的唯一简单的事情就是将它们传递给一个变量函数 我的问题是,为什么它们是这样设计的?在任何纯函数式语言(如CPP)中,列表的标准方法都是cons样式的模式匹配:处理列表的第一个参数,对其余

与C++的可变模板相比,CPP(C/C++预处理器;为了简单起见,我将在这个问题中将其视为一种单独的语言)中的可变宏非常有限。本质上,可变宏只是带有参数的宏,其参数允许包含逗号。这并没有提供简单的方法来计算参数、逐个操作参数等。这些都是可能的,但需要复杂、混乱且编译速度慢的黑客,如中所述。使用
VA_ARGS
可以做的唯一简单的事情就是将它们传递给一个变量函数

我的问题是,为什么它们是这样设计的?在任何纯函数式语言(如CPP)中,列表的标准方法都是cons样式的模式匹配:处理列表的第一个参数,对其余参数进行递归,并为空列表设置基本情况。标准委员会成员对这种方法相当熟悉

为什么CPP的可变宏不采用这种方法?变量宏是否仅仅被视为包装变量函数的一种方式,因此不需要对参数列表进行操作?是否有一些潜在的问题使得允许可变宏递归变得不切实际?还是


注意:我不是在寻找表格“因为人们不应该想要可变宏”的答案/注释。像boost.preprocessor这样的东西的存在表明理性的人希望以非平凡的方式使用预处理器。也不寻求关于为什么其他设计是好主意/坏主意的个人意见。我试图从时间上找出实际的推理。

< P>变量宏,从C.< /P>继承为C++。 写了一篇向C添加变量宏的论文

国家:

此建议允许宏的作者声明它需要 变量数量的参数,并替换尾随参数 整体而言

[……]

有可能提供更多的设施,但这一点已被搁置 进一步的建议

一个问题是是否应该允许零实际参数 以匹配尾部参数。已经决定不允许这样做,因为 这更适合单独提出另一项提案

因此,计划是添加最需要的功能(一个可用于填充printf调用的宏),并为以后的论文留下进一步的扩展

在C++中,宏是二等公民。C++很少使用新的宏语法或特征进行创新,而是在没有宏的情况下解决问题的方法。 C没有进一步创新


添加到C中的实际vararg宏来自于从该宏派生出来的论文,但该宏在这一决定背后有着最清晰的动机文本。

中的意图显然只是作为可变函数的包装器。可变宏是在C99中引入的,后来在C++11中引入。C99基本原理V5.10 6.10.3提供了以下解释:

C99的一个新特性:C89引入了一种标准机制,用于使用 参数数量可变,但不允许以任何方式使用相同的参数编写宏 财产。例如,无法编写类似于调用printf的宏

该设施现在可用。宏定义使用省略号的方式与指示 变量参数列表。但是,由于宏替换是文本的而不是运行时的,因此 不同的机制用于指示替换参数的位置:标识符
\uuu VA\u ARGS\uuu
。这将替换为与省略号匹配的所有参数,包括它们之间的逗号


虽然
\uu VA\u ARGS\uu
还有一些其他用法,但这可能更像是巧合。例如,您可以使用可变宏来计算初始值设定项列表中的项数。

已经有几个很好的答案,但我想继续介绍它们的综合,以及用户694733提到的一个要点。鉴于提案文件和语言标准中的描述,该提案的唯一设想用例似乎是委托给printf风格的变量函数

该提案提到允许零实际参数“更适合另一提案”。我最初认为这意味着“不允许零争论允许这个提案与另一个提案兼容”,但事实上,这个意思似乎更接近于“允许零争论应该是另一个提案的一部分”。虽然我找不到可以引用的提案,但我确实找到了,建议使用
\uu VA\u COUNT\uu
关键字。假设这一评论至少代表了他的另一个提案的一部分,那么对于更精细地使用可变宏来说,
\u VA\u COUNT\u
是一种需要的东西


N580(及其后继者)似乎代表了一个流行且无争议的建议,即允许变量通过宏,而
\uuuu VA\u COUNT\uuuu
是更丰富的变量预处理的一个组成部分(通过代码<宏代码AgsS1)/代码>代码>宏AgsSux2 < /Cube >等,或者通过其他未知机制,只有第一个建议达成一致。

C.C++被设计成很容易让C程序员切换到(如此大量的向后兼容性)。有什么理由让你必须在宏中处理它,而不是将繁重的工作委托给实际的函数吗?好的,可变宏所需的标准细节可能不到可变模板的1/10。预处理器本身不是设计为一种语言,因此它非常有限的事实不应该被忽略让人惊讶的是?无论如何,答案可能是你不应该在