【问题标题】:C4003: Not enough actual parameters for macro in C++C4003:C++ 中宏的实际参数不足
【发布时间】:2017-10-28 02:44:11
【问题描述】:

看看这个

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

【问题讨论】:

    标签: c++ macros preprocessor


    【解决方案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 之前没有得到评估,而且它们根本没有得到评估 ,因为替换列表中没有提到它们。

    有人可以建议如何解决它吗?

    只要您要扩展的内容是 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 使用您期望的参数调用。

    【讨论】:

      猜你喜欢
      • 2012-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多