c++ - C4003 : Not enough actual parameters for macro in C++

标签 c++ macros preprocessor

看看这个

#define getFourth( _1,_2,_3, _4,... )  _4   //select the 4th parameter 
#define some_type(x) type, x  

getFourth
(   some_type(1),
    some_type(2),
    some_type(3)
)

我认为它会扩展为 getFourth(type, 1, type, 2, type, 3) 所以我们应该选择 2 个(因为 2 是第四个参数)。相反,我收到警告“C4003 没有足够的实际参数用于宏“getFourth”。看来 getFourth 将 some_type(1) 作为第一个元素,some_type(2) 作为第二个元素,some_type(3) 作为第三个元素。由于它预计至少有 4 个参数,因此我们收到了警告。有人可以建议如何修复它吗?

最佳答案

I thought it expands to getFourth(type, 1, type, 2, type, 3) so we shall have 2 selected (since 2 is the 4th parameter)

宏不是这样工作的。宏扩展是从外向内进行的。此外,还有两种扩展机会:(1) 在参数替换期间,(2) 之后生成替换列表。仅当宏中的参数与替换列表中的参数相对应时,才会发生参数替换扩展(并且该参数未使用 # 运算符进行字符串化或参与粘贴 (##))。

例如,如果我们有:

#define foo(b,c) b c
getFourth(some_type(1),some_type(2),some_type(3),foo(some_type,(4)),x)

然后getFourth现在有5个参数,因此可以调用它。扩展的第一步是论证替换; getFourth 的替换列表是_4,它只提到了一个参数。相应的参数是foo(some_type,(4))。由于 _4 未进行粘贴或字符串化,因此处理器可以计算 foo(some_type,(4))。结果是 some_type (4),它进一步扩展为 type, 4。所以现在,type, 4 取代了 _4。我们已经完成了参数替换。

我们只剩下类型,4。这里又进行了一次重新扫描,但在此步骤中没有任何反应。但请注意,some_type(1)some_type(2)some_type(3) 不仅之前未进行评估getFourth,但它们根本没有被评估,因为替换列表中没有任何内容提到它们。

Can someone please suggest how to fix it?

只要您要扩展的内容是 getFourth 的参数 1 到 3,它们甚至不会计算。但是您可以将其设为一个带括号的列表,然后应用宏,使用类似于我上面所做的技巧:

#define CALL(a,b) a b
CALL(getFourth,(some_type(1),some_type(2),some_type(3))).

现在,getFourth(some_type(1),some_type(2),some_type(3)) 只是 CALL 的参数,其中提到了这两个参数。因此,在参数替换期间,getFourth 本身会“求值”(因为这不足以调用类似对象的宏,所以它就保持原样),并被放入 a(some_type(1),some_type(2),some_type(3)) 计算并放入 b 中。该评估变为 (type, 1,type, 2,type, 3)。所以你最终得到了getFourth (type, 1,type, 2,type, 3)。现在会进行重新扫描,在此期间使用您期望的参数调用 getFourth。

关于c++ - C4003 : Not enough actual parameters for macro in C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46985736/

相关文章:

c# - MySQL预处理器优化

apache-flex - 是否可以在Adobe Flex中进行#define?

c++ - 在编译时检查静态函数是否在类中可用

c++ - 按行、列和深度顺序打印多维 vector

c++ - 不可变数据结构还是 const 变量?

macros - Lisp SBCL 宏引用列表作为参数

Drupal 8 - 根据分类术语或其他添加主体类别

C++ 程序,用 g++ 编译

c++ - 宏不通过直接调用扩展,而是通过间接调用扩展

单位与多位的 c 位操作