看看这个
#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个参数所以我们有警告。有人可以建议如何解决它?
答案 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。