C4003:C ++中宏的实际参数不够

时间:2017-10-28 02:44:12

标签: 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是第4个参数)。相反,我收到了警告"C4003 not enough actual parameters for macro 'getFourth"。似乎getFourth将some_type(1)视为第一个元素,some_type(2)视为第二个元素,some_type(3)视为第三个元素。因为它预计至少有4个参数所以我们有警告。有人可以建议如何解决它?

1 个答案:

答案 0 :(得分:1)

我认为它扩展到getFourth(type,1,type,2,type,3)所以我们将选择2个(因为2是第4个参数)

这不是宏的工作方式。宏扩展是从外部发生的。此外,有两种扩展机会:(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。我们已完成参数替换。

我们离开type, 4。这里还有一个重新扫描,但在此步骤中没有任何反应。但请注意,some_type(1)some_type(2)some_type(3)不仅未在getFourth 之前进行评估,但他们没有& #39; t得到所有的评估,因为替换列表中没有任何内容提及它们。

有人可以建议如何修复它吗?

只要您想扩展的内容是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。