看看这个
#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/